0
votes

EDIT: Thank to Joe's advice, I will make my question more specific. Actually I need to code a function in Stata which takes variables A,B,C,D,... as inputs and a variable Y as output which can be evaluated with usual Stata functions/commands like "generate dummy=2*myfun(X) if ..."

The function itself contains numerical calculations. A pseudo Stata code will look like

myfun(X)
 gen Y=0.5*X if X==1
 replace Y=31-X if X==2
 replace Y=X-2 if X==3
 .... a long list
return(Y) 

Notice that X can be a huge set of different Stata variables and the numerical calculations are rather long inside the function. That's why I would like to use a function. I guess that the native "program" command in Stata is not suitable for this type of problem because it cannot take variables as input/output.

1
I would suggest you explain a bit more of what you're doing here. Code Conversion explicitly isn't on topic for StackOverflow; rather, make the question sufficiently detailed that a stata programmer could answer your question without knowing SAS, and leave the SAS code in it just to add detail for anyone who does happen to know both. - Joe

1 Answers

1
votes

(ANSWER TO ORIGINAL QUESTION)

I have never used SAS, but at a wild guess you want something like

foreach v in A B C D { 
    gen test`v' = 0.5 * (`v' == 1) + 0.6 * (`v' == 2) + 0.7 * (`v' == 3)  
}

or

foreach v in A B C D { 
    gen test`v' = cond(`v' == 1, 0.5, cond(`v' == 2, 0.6, cond(`v' == 3, 0.7, .))) 
}

But hang on; that middle line also looks like

    gen test`v' = (4 + `v') / 10 

(ANSWER TO COMPLETELY DIFFERENT REVISED QUESTION)

This can be done in various ways. As above you could have a loop

  foreach v in A B C D { 
      gen test`v' = 0.5 * `v' if `v' == 1 
      replace test`v' = 31 - `v' if `v' == 2 
      replace test`v' = `v' - 2 if `v' == 3 
  }   

The question says "I guess that the native "program" command in Stata is not suitable for this type of problem because it cannot take variables as input/output." That guess is completely incorrect. You could write a program to do this too. This example is schematic, not definitive. A real program would include more checks and error messages to match any incorrect input. For detailed advice, you really need to read the documentation. One answer on SO can't teach you all you need to know even to write simple Stata programs. In any case, the example is evidently frivolous and/or incomplete, so a complete working example would be pointless or impossible.

   program myweirdexample 
       version 13 
       syntax varlist(numeric), Generate(namelist) 

       local nold : word count `varlist'
       local nnew : word count `generate' 
       if `nold' != `nnew' { 
            di as err "`generate' does not match `varlist'" 
            exit 198 
       }

       local i = 1 
       quietly foreach v of local varlist { 
            local new : word `i' of `generate' 
            gen `new' = 0.5 * `v' if `v' == 1 
            replace `new' = 31 - `v' if `v' == 2 
            replace `new' = `v' - 2 if `v' == 3             
            local ++i 
       }
   end 

Footnote on terminology: The question uses the term function more broadly than it is used in Stata. In Stata, commands and functions are distinct; "function" is not a synonym for command.

Second footnote: Check out recode. It may be what you need, but it is best for mapping integer codes to other integer codes.

Third footnote: An example of a needed check is that the argument of generate() should be variable names that are legal and new.