Announcement

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

  • bootstrap SE for SEM latent growth mediation model

    I have created an SEM latent growth mediation model using FIML (Stata 14). I need to get bootstrap standard errors (SE) and confidence intervals for various path in these models. As far as I can tell, using the "estat teffects” Stata command after the SEM model only gives me the Sobel SE. I need bootstrap SE and confidence intervals, as this is the publication standard in most journals these days.

    If you have suggestions or syntax for obtaining the bootstrap SE and confidence intervals for the direct, indirect, and total path for an SEM mediation model in Stata, I would be very grateful.

    Thank you!

    In case it is helpful, here is the syntax for the SEM model.


    sem (Outcome1<-I@1 S@0 _cons@0) ///
    (Outcome2<-I@1 S@1 _cons@0) ///
    (Outcome4<-I@1 S@2 _cons@0) ///
    (Outcome6<-I@1 S@3 _cons@0) ///
    (Mediator1 <- IV1 control1 control2 _cons) ///
    (Mediator1 <- IV2 control1 control2 _cons) ///
    (Mediator2 <- IV1 control1 control2 _cons) ///
    (Mediator2 <- IV2 control1 control2 _cons) ///
    (Mediator3 <- IV1 control1 control2 _cons) ///
    (Mediator3 <- IV2 control1 control2 _cons) ///
    (I <- IV1 IV2 control1 control2 _cons) ///
    (S <- IV1 IV2 control1 control2 _cons), ///
    latent(I S) ///
    var(e.Outcome1@var e.Outcome2@var e.Outcome4@var e.Outcome6@var) ///
    method(mlmv) vce(cluster schoolvar)

    estat teffects

  • #2
    The UCLA web-page listed below has an example. It's for a simpler model than yours, but it might help you get started down the right track.
    --
    Bruce Weaver
    Email: [email protected]
    Version: Stata/MP 18.5 (Windows)

    Comment


    • #3

      Hi Bruce- Thanks for your response. I came across the ats.ucla.edu resource in my search for information on how to approach this question. The problem that I encountered with this approach (which I pasted below), is that it lumps all the indirect effects together. That would be fine if I only had one indirect path. However, in my model I have 6 indirect paths and I would like to isolate each path independently. In other words, it would be useful to me to identify which paths are mediating, rather than obtaining a global indirect path SE and confidence interval. I am not sure how to modify this syntax to work for my needs. Thank you!

      program indireff, rclass
      sem (read <- math)(science <- read math)
      estat teffects
      mat bi = r(indirect)
      mat bd = r(direct)
      mat bt = r(total)
      return scalar indir = el(bi,1,3)
      return scalar direct = el(bd,1,3)
      return scalar total = el(bt,1,3)
      end


      bootstrap r(indir) r(direct) r(total), reps(200): indireff

      Comment


      • #4
        Indirect effects are products of specific coefficients in your model, e.g. from IV1 to Mediator1 to Outcome1. According to the help file,SEM returns a matrix containing the various parameter estimates from the model in e(b) so you could calculate specific indirect effects "by hand" and do a subsequent bootstrap. This would be a bit tricky and tedious, but doable.

        Richard T. Campbell
        Emeritus Professor of Biostatistics and Sociology
        University of Illinois at Chicago

        Comment


        • #5
          One loose example of bootstrapping non-linear effect purely on some loose data. Proceedure is similar for other effects aswell.

          Code:
          sem (z <- x1 x2 x3) ///
              (y <-z x1 x2 x3 ),
          
          ------------------------------------------------------------------------------
                       |                 OIM
                       |      Coef.   Std. Err.      z    P>|z|     [95% Conf. Interval]
          -------------+----------------------------------------------------------------
          Structural   |
            z <-       |
                    x1 |   .1657031   .1426956     1.16   0.246    -.1139751    .4453813
                    x2 |   .8332578   .1434855     5.81   0.000     .5520314    1.114484
                    x3 |    3.61658   .2066624    17.50   0.000     3.211529    4.021631
                 _cons |   26.05748   .0997644   261.19   0.000     25.86194    26.25301
            -----------+----------------------------------------------------------------
            y <-       |
                     z |    .029287   .0020666    14.17   0.000     .0252366    .0333374
                    x1 |  -.2240688    .032012    -7.00   0.000    -.2868113   -.1613264
                    x2 |  -.0549752   .0322334    -1.71   0.088    -.1181515    .0082012
                    x3 |   .3885038   .0469582     8.27   0.000     .2964675    .4805401
                 _cons |   3.053266   .0583149    52.36   0.000     2.938971    3.167562
          -------------+----------------------------------------------------------------
               var(e.z)|   31.34179   .4083296                      30.55161    32.15241
               var(e.y)|   1.577174   .0205479                      1.537411    1.617966
          ------------------------------------------------------------------------------
          
          
          //Non-linear/Product of x1 on z and z on y:
          ==========================================================
              nlcom _b[z:x1]*_b[y:z]
          
          ------------------------------------------------------------------------------
                       |      Coef.   Std. Err.      z    P>|z|     [95% Conf. Interval]
          -------------+----------------------------------------------------------------
                 _nl_1 |   .0048529   .0041931     1.16   0.247    -.0033654    .0130713
          ------------------------------------------------------------------------------
          
          //Bootstrap the non-linear effect:
          
          capture program drop bootxz
          program bootxz, rclass
           sem (z <- x1 x2 x3) ///
              (y <-z x1 x2 x3 ),
           return scalar est1 =  _b[z:x1]*_b[y:z]
           end
          bootstrap r(est1), reps(5) : bootxz
          
          
          (running bootxz on estimation sample)
          
          Bootstrap replications (5)
          ----+--- 1 ---+--- 2 ---+--- 3 ---+--- 4 ---+--- 5
          .....
          
          Bootstrap results                               Number of obs     =     11,783
                                                          Replications      =          5
          
                command:  bootxz
                  _bs_1:  r(est1)
          
          ------------------------------------------------------------------------------
                       |   Observed   Bootstrap                         Normal-based
                       |      Coef.   Std. Err.      z    P>|z|     [95% Conf. Interval]
          -------------+----------------------------------------------------------------
                 _bs_1 |   .0048529   .0042099     1.15   0.249    -.0033982    .0131041
          ------------------------------------------------------------------------------
          You need to change the reps(*) number according to as many times you wish to replicate. For several estimations, perhaps you would be better of to write a programme and run through loops. After the -sem- commands are run, typing -sem, coefleg- will give you the coefficient legends which you can plug into your bootstrap commands for direct, indirect or total effect bootstrapping.


          Roman

          Comment


          • #6
            Hi Roman-
            Your example is very helpful. I will implement this approach with my data.
            Thank you!

            Natalia

            Comment


            • #7
              Hi Natalia, Hi Roman,

              I came across your example on the estimation of bootstrapping the indirect effects, as described above. Your example was very useful for me.

              I wonder if you could have a look at my estimation and give me some feedback. I have a three-way mediation and am not sure if I have modified the procedure appropriately.

              And could you please give me a hint, how I can run through loops to speed up the whole procedure. I need to go through 2000 replications...

              Thank you very much in advance.

              Alex

              Code:
              *Bootstrapping 
              
              //Non-linear/Product of entr_persfit on VARIETY and VARIETY on BALSKI and BALSKI on INTENTIONS:
              ==========================================================
                  estat stdize: nlcom _b[VARIETY:entr_persfit]*_b[BALSKI:VARIETY]*_b[INTENTION:BALSKI], level (95)
                  
                  //Bootstrap the non-linear effect:
              
              capture program drop bootxz
              program bootxz, rclass
              sem (VARIETY -> BALSKI) (VARIETY -> variety_int_subjects) (VARIETY -> variety_imp_subjects) (VARIETY -> many_hobbies) (BALSKI -> INTENTION) (BALSKI -> balanced_skills_work) (BALSKI -> balanced_skills_education) (INTENTION -> ent_sou_inf) (INTENTION -> ent_prob) (INTENTION -> ent_int_unc) (entr_parent -> VARIETY) (entr_parent -> BALSKI) (entr_parent -> INTENTION) (entr_persfit -> VARIETY) (entr_persfit -> BALSKI) (entr_persfit -> INTENTION) (female -> VARIETY) (female -> BALSKI) (female -> INTENTION) (Kohort_d -> VARIETY) (Kohort_d -> BALSKI) (Kohort_d -> INTENTION) if miss_sem_dropnumber!=5, method(mlmv) latent(VARIETY BALSKI INTENTION ) cov( entr_persfit*entr_parent female*entr_parent female*entr_persfit Kohort_d*entr_parent Kohort_d*entr_persfit Kohort_d*female) nocapslatent,
              return scalar est1 =  _b[VARIETY:entr_persfit]*_b[BALSKI:VARIETY]*_b[INTENTION:BALSKI]
               end
              bootstrap r(est1), reps(2) level(95) : bootxz

              Comment

              Working...
              X