0
votes

I have written a tiny program for simulation of multiple regression results. I can run this on a line by line basis (using actual values instead of the syntax command), but when I put it in an ado, it doesn't work properly.

The basic idea is use drawnorm to generate a dataset, run regression on it, then do it over and over using the simulate option. I am using a single command line [powersim3, ry1(.30) ry2(.30) r12 (.30) n (282)] to run the syntax below (encased in the *****).

******
 program define powersim3, rclass
 syntax, ry1(real)ry2(real)r12(real)n(
real) [my(real 0)m1(real
0)m2(real 0)m3(real 0)sy(real 1) ///
    s1(real 1)s2(real 1)s3(real 1)alpha(real .05)help]
matrix m = (`my', `m1', `m2')
matrix sd = (`sy', `s1', `s2')
matrix r = (1, `ry1', `ry2'\ `ry1' , 1 , `r12'\ `ry2' , `r12', 1)
drawnorm y x1 x2, n(`n') corr(r) means(m) sds(sd)
regress y x1 x2
end

simulate _b _se, reps(10000): powersim3
*****

It appears the issue is that the simulate command isn't recognizing the powersim3 command above (this works if you leave simulate out). I expect there is a simple solution here -- but I'm not proficient enough in Stata to know what the simple answer is. Any suggestions would be very helpful.

1
I think you need to use eclass not rclass . Details hereMetrics
eclass provides the same error messages. Also, this is not a problem that I want to apply bootstrap to. I want a new random sample from the population each time as this will more correctly estimate the underlying construct (Power)Chris Aberson
Cross-posted to Statalist. Better to declare that explicitly.Nick Cox
My apologies re: Statalist. Is there a way to delete those messages? The interface here is far simpler.Chris Aberson
You are getting better attention on Statalist. There is no deletion retrospectively there: see stata.com/support/faqs/resources/statalist-faq/#comment But if you prefer this forum, don't post on Statalist!Nick Cox

1 Answers

1
votes

There are several errors in your code:

  1. Your program powersim3 requires the options ry1(), ry2(), r12(), and n(). In your call to simulate you omitted those options.
  2. Your program must start by deleting the variables y x1 x2; otherwise it will return errors on the second iteration and later as it then tries to generate variables that already exist.
  3. The syntax statement contains various problems with spaces being left out.

Fixing all that, a working example is:

clear all
program define powersim3, rclass
    syntax, ry1(real) ry2(real) r12(real) n(real) ///
    [ my(real 0) m1(real 0) m2(real 0) m3(real 0) sy(real 1) ///
    s1(real 1) s2(real 1) s3(real 1) alpha(real .05)]

    drop _all

    tempname m sd r
    matrix `m' = (`my', `m1', `m2')
    matrix `sd' = (`sy', `s1', `s2')
    matrix `r' = (1, `ry1', `ry2'\ `ry1' , 1 , `r12'\ `ry2' , `r12', 1)
    drawnorm y x1 x2, n(`n') corr(`r') means(`m') sds(`sd')
    regress y x1 x2
end

simulate _b _se, reps(10000): ///
    powersim3, ry1(.30) ry2(.30) r12(.30) n(282)

Edit

In order to package that entire process in one command you need to store two .ado files: powersim3.ado and powersim3_simulator.ado. The former is the command that the user calls and the latter is the command that simulate calls within powersim3. Since powersim3 will erase all data currently in memory and replaces it with the results from the simulation, I insist that the user specifies the clear option. This safeguard is convention in the Stata world. I added an option reps() such that the user can specify the number of replications. The remaining options are captured by the * in the syntax command of powersim3. This means that whatever other options the user specifies are stored in the local macro `options'. These options are all passed on to the powersim3_simulator command.

*--- begin file powersim3.ado

program define powersim3
    syntax , clear [ reps(integer 100) * ]
    simulate _b _se, reps(`reps') : powersim3_simulator, `options'
end

*--- end file powersim3.ado

*--- begin file powersim3_simulator.ado

program define powersim3_simulator
    syntax, ry1(real) ry2(real) r12(real) n(real)                ///
        [ my(real 0) m1(real 0) m2(real 0) m3(real 0) sy(real 1) ///
        s1(real 1) s2(real 1) s3(real 1) alpha(real .05)]

    drop _all

    tempname m sd r
    matrix `m' = (`my', `m1', `m2')
    matrix `sd' = (`sy', `s1', `s2')
    matrix `r' = (1, `ry1', `ry2'\ `ry1' , 1 , `r12'\ `ry2' , `r12', 1)
    drawnorm y x1 x2, n(`n') corr(`r') means(`m') sds(`sd')
    regress y x1 x2
end

*--- end file powersim3_simulator.ado


powersim3_simulator is just a helper program, and often you can add helper programs in the same .ado file, something like so

*--- begin foo.ado file

program define foo
    ...
    bar
    ...
end

program define bar
    ...
end

*--- end foo.ado file

This is convenient as it reduces the number of files necessary for a program, but this won't work in this case. The reason is that the program bar (or in your case powersim3_simulator) will be local to the program foo (or in your case powersim3), which means simulate won't be able to find it. So for this problem you really need to store two .ado files to do what you want.