Announcement

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

  • Looping over program define

    Hi all,

    I'm performing a mediation analysis on regression discontinuity results, and have encountered the need to write my own program for the first time. The program below should store the indirect effect (a*b) of variable tlf_`x'_t1 on ach_resid_t1 so that I can bootstrap the coefficients and recover standard errors and confidence intervals. The issue I am having is that I want to run the program and bootstrap the results for each of 9 tlf variables separately. I've tried to do this using a forvalues loop, but stata "breaks" the loop when it encounters the end command. Any ideas on how I can get around this, so that I don't have to define the program and bootstrap for each component separately?

    forvalues x=1/9 {

    program define indirect_eff_tlf`x', rclass
    reg tlf`x'_t1 me_in cenrating me_rating_int math i.year i.grade $tchr_cov, cluster(id)
    gen a = _b[me_in]

    reg ach_resid_t1 tlf`x'_t1 me_in cenrating me_rating_int math i.year i.grade $tchr_cov, cluster(id)
    gen b = _b[tlf`x'_t1]

    gen indir_eff_tlf`x' = a*b
    sum indir_eff_tlf`x'
    return scalar ie_tlf`x' = r(mean)

    drop a b indir_eff_tlf`x'

    end

    bootstrap ie_tlf`x'=r(ie_tlf`x'), seed(12345) reps(50): indirect_eff_tlf`x'

    }


    Thanks so much for your thoughts!

    Best,
    Mindy

  • #2
    You have introduced all sorts of unnecessary complexity here. There is no reason to define 9 separate programs that all do the same thing, just with a different variable. You use variables to hold interim results that are constants, when scalars or local macros would be more suitable.

    Code:
    program define indirect_eff_tlf, rclass // JUST ONE PROGRAM
       args x
        // MIGHT WANT TO INCLUDE SOME VERIFICATION THAT X IS OK
        // MAYBE -assert inrange(`x', 1, 9)-
        reg tlf`x'_t1 me_in cenrating me_rating_int math i.year i.grade $tchr_cov, cluster(id)
       local a = _b[me_in] // DON'T GENERATE A VARIABLE TO HOLD A CONSTANT
        reg ach_resid_t1 tlf`x'_t1 me_in cenrating me_rating_int math i.year i.grade $tchr_cov, cluster(id)
       local b = _b[tlf`x'_t1] // DON'T GENERATE A VARIABLE TO HOLD A CONSTANT
    // gen indir_eff_tlf = `a'*`b' // AGAIN, DON'T NEED A VARIABLE HERE; ACTUALLY DON'T NEED ANYTHING HERE
        // sum indir_eff_tlf`x': CODE DELETED BECAUSE THIS IS NOT A VARIABLE
        return scalar ie_tlf = `a'*`b' // JUST RETURN `a'*`b' WITHOUT ANY FURTHER ADO
    end
    
    set seed 12345 // NO NEED TO RE-SET SEED TO SAME NUMBER INSIDE LOOP
    forvalues x=1/9 {
    
        bootstrap ie_tlf`x'=r(ie_tlf), /*seed(12345)*/ reps(50): indirect_eff_tlf `x'
    
    }
    I have not fully tested this, but I think it will work. In fact, the program could be improved further by using a -syntax- statement to pass a variable name instead of a number between 1 and 9, so that it could work more generally. But this will suffice for your purposes and spares you the effort of learning the -syntax- command. (That said, when you have time with less pressure, learning to use -syntax- amply rewards the effort required.)

    Added later: I had not seen Daniel Klein's response to another copy of this post (which is largely the same as mine) when I responded to this one.
    Last edited by Clyde Schechter; 08 Feb 2015, 15:36.

    Comment


    • #3
      Thank you, Clyde! This detail is really helpful, and will help me simplify work with stored estimates in the future.

      Best,
      Mindy

      Comment


      • #4
        Hi all, I am new to this forum (as active user). I know this is an old post but I am hoping to receive some guidance on a similar issue that I am facing. I am very inexperienced with defining a program, so probably there are very obvious errors in my code of which I hope you can help me with.

        I am running a mediation analysis using gsem (including controls, but I have not added them to the code below), and want to bootstrap the standard errors of the estimates of the direct and indirect effects. I want to run the program for a range of different variables, defined in my "for each x of varlist..." line, and then afterwards bootstrap the direct and indirect effects for the same set of variables. This does not work, but I don't really know how to fix it. When running the code for one dependent variable without the loop the code works fine.

        Thanks for your help! Best, Juliette

        capture program drop bootmm
        program bootmm, rclass
        syntax [if] [in]
        foreach x of varlist A B{
        gsem (`x' <- ethnic c_vote_ e_vote_ p_vote_ )(c_vote_ <- ethnic )(e_vote_ <- ethnic )(p_vote_ <- ethnic )(`x''' <- ethnic c_vote_ e_vote_ p_vote_) `if' `in'
        return scalar indtotal`x' = _b[`x':c_vote_]*_b[c_vote_:ethnic] + _b[e_vote_:ethnic]*_b[`x''':e_vote_] + _b[p_vote_:ethnic]*_b[`x':p_vote_]
        return scalar ind_c`x' = _b[`x':c_vote_]*_b[c_vote_:ethnic]
        return scalar ind_e`x' = _b[e_vote_:ethnic]*_b[`x':e_vote_]
        return scalar ind_p`x' = _b[p_vote_:ethnic]*_b[`x':p_vote_]
        return scalar ditotal`x' = _b[`x':ethnic] + _b[c_vote_:ethnic]*_b[`x':c_vote_] + _b[e_vote_:ethnic]*_b[`x':e_vote_] + _b[p_vote_:ethnic]*_b[`x':p_vote_]
        }
        end

        foreach x of varlist A B{
        bootstrap r(indtotal`x') r(ind_c`x') r(ind_e`x') r(ind_p`x') r(ditotal`x'), bca reps(50) nodots: bootmm
        }
        Last edited by Juliette de Wit; 04 Feb 2022, 10:48.

        Comment


        • #5
          Well, you don't provide any example data for testing, and you don't explain in what way the code "doesn't work." So there isn't much to go on.

          The only thing that jumps out at my eye is that both the -gsem- command and the first -return scalar- command include -`x'''-, which has to be a syntax error. I think you mean just -`x'- in those places.

          If that doesn't solve the problem, when posting back give example data, using the -datatex- command, and also show whatever error messages and other output you are getting so those who want to help you have some idea what is going on and something to work with for troubleshooting. Also, unless it is blatantly obvious, explain in what way the output from Stata differs from what you are seeking.

          If you are running version 17, 16 or a fully updated version 15.1 or 14.2, -dataex- is already part of your official Stata installation. If not, run -ssc install dataex- to get it. Either way, run -help dataex- to read the simple instructions for using it. -dataex- will save you time; it is easier and quicker than typing out tables. It includes complete information about aspects of the data that are often critical to answering your question but cannot be seen from tabular displays or screenshots. It also makes it possible for those who want to help you to create a faithful representation of your example to try out their code, which in turn makes it more likely that their answer will actually work in your data.

          Comment

          Working...
          X