Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • if & else if syntax

    Dear Stata users,

    I wrote a very simple program to caculate efficacy coefficient. The program is as follows. However, Stata only run the second piece of program (i.e. the second if sentence). Can anybody point out where the problem lay, thank you.

    Code:
    program define efcoef
    
    syntax varlist[, Low(integer 100) High(integer 100) help]
    
     tokenize `varlist'
    
     if ("`help'"!="help" & "`low'`high'"=="") {
      foreach v of varlist `varlist' {
       tempvar `v'min `v'max `v'mean
       egen ``v'min'=min(`v')
       egen ``v'max'=max(`v')
       egen ``v'mean'=mean(`v')
       gen efcoef_`v'=round((`v'-``v'min')/(``v'max'-``v'min')*40+60, 0.01)
       label var efcoef_`v' "efficacy coef: min-max of `v'"
      }
     }
    
     if ("`help'"!="help" & "`low'`high'"!="") {
      foreach v of varlist `varlist' {
       tempvar `v'min `v'max `v'mean
       egen ``v'min'=min(`v')
       egen ``v'max'=max(`v')
       egen ``v'mean'=mean(`v')
       gen efcoef_`v'=round((`v'-``v'min')/(``v'max'-``v'min')*40+60, 0.01)
       gen efcoef_`v'_2=round((`v'-`low')/(`high'-`low')*40+60, 0.01)
       label var efcoef_`v' "efficacy coef: min-max of `v'"
       label var efcoef_`v'_2 "efficacy coef: low-high of `v'"
      }
     }
    
     if ("`help'"=="help") {
      display "efcoef var will generate ecoef_var=(var-`v'min)/(`v'max-`v'min)*40+60"
      display "efcoef var, low(int) high(int) help"
     }
    
    end

  • #2
    If the options low() or high() are not specified then they get the default value that you specified to be 100. So "`low'`high'" will never be empty and you'll never end up in the first block.

    If I want to take special actions when an option is not specified, I often put them in the syntax as an numlist with a maximum number of numbers of 1, e.g.: low(numlist max=1 integer) . In that case the local macro `low' will be empty when the option low() has not been specified.

    ---------------------------------
    Maarten L. Buis
    University of Konstanz
    Department of history and sociology
    box 40
    78457 Konstanz
    Germany
    http://www.maartenbuis.nl
    ---------------------------------

    Comment


    • #3
      low() and high() have default numeric values. So, whether you specify values or not the string

      Code:
      "`low'`high'" 
      will never be empty. One way forward is to let each option specify a numlist with one element.

      Your program can be simplified.

      If you want to calculate a single minimum and maximum, use the returned values from summarize, not three temporary variables and egen each time around the loop. You never use the mean, so there is no point to calculating it. To show two decimal places, use a display format, not round(). You never use the results of tokenize, so that looks redundant too.

      I haven't tested this code, and don't understand the context, which you don't give any way, but this may help.

      Further things to think about.

      * The user specifies low() but not high() or vice versa. This program would fail.

      * Whether the new names implied are all indeed new and legal.

      * Support for if and in.

      * A version statement

      Code:
      program define efcoef
      syntax varlist [, Low(numlist int max=1) High(numlist int max=1) help]
      
      if "`help'" == "help" {
      display "efcoef var will generate ecoef_var=(var-`v'min)/(`v'max-`v'min)*40+60"
      display "efcoef var, low(int) high(int) help"
      exit 0
      }
      
      foreach v of varlist `varlist' {
      summarize `v', meanonly
      gen efcoef_`v' = (`v'- r(min))/(r(max) - r(min))*40+60
      label var efcoef_`v' "efficacy coef: min-max of `v'"
      format efcoef_`v' %3.2f
      
      if "`low'`high'" != "" {
      gen efcoef_`v'_2 = (`v'-`low')/(`high'-`low')*40+60
      label var efcoef_`v'_2 "efficacy coef: low-high of `v'"
      format efcoef_`v'_2 %3.2f
      }
      }
      end
      EDIT: Crossed with @Maarten Buis's answer, which makes the same main point. The forum software has reversed all my indents, so this needs tidying up!
      Last edited by Nick Cox; 09 Dec 2019, 01:33.

      Comment


      • #4
        Dear Maarten Buis & Nick Cox, thank you so much for getting me out! You both reveal an important information in syntax of Stata that I haven't yet mastered. And much appreciate Mr. Nick's neat and simplified program and kind tips.

        Comment

        Working...
        X