Announcement

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

  • SEM with Fixed Effects in Allison's Fixed Effects Regression Models (2009)

    Dear Stata Forum,

    With great interest I'm reading Allison's booklet on Fixed Effects Regression Models. Chapter 2 opened my eyes on my erroneous assumption that the fixed effects method is outdated by mixed effects approaches. The book uses clear examples for which the data can be downloaded from the website of Statistical Horizons and for which Stata commands are in the Appendix.

    The book extends the linear fixed effects models to the structual equation modeling (SEM) paradigm. For the SEM approach the booklet contains an Appendix with MPlus commands. I don't have access to MPlus and am wondering if these models can be estimated using Stata's recent SEM commands. Does anyone have (tips for) Stata code to estimate these models.

    REFERENCE: Allison, Paul D. (2009) Fixed Effects Regression Models. Thousand Oaks, CA: Sage Publications.


    Kind regards, Adriaan Hoogendoorn


  • #2
    Hello "awhoogendoom" (please re-register with your name and family name, you can do this by clicking on "contact us", below to the right),

    Regarding Stata codes on SEM, I have two suggestions:

    First, the manual (Stata Structural Equation Modeling Reference Manual): sincerely, this is one of the "liveliest" manuals I've ever read. Great pleasure.

    Second, an excellent book on the matter: Alan C. Acock, Discovering Structural Equation Modeling Using Stata, revised edition, 2013, StataPress.

    About fixed effects in the context of latent growth curves, I share with you an interesting excerpt (page 153): "The overall trajectory is referred to as fixed effect; it is what would happen if everybody had the same trajectory. For many purposes, just identifying this fixed effect is sufficient".

    Best,

    Marcos
    Best regards,

    Marcos

    Comment


    • #3
      You can get Allison's data sets at http://www.statisticalhorizons.com/resources/data-sets

      Here is the code I used to replicate his tables 6.1 and 6.2. It seems to work pretty well. 6.3 has caused me grief though, and I've never come up with a really good way of doing it. But, I haven't tried lately either.

      Code:
      /* Tables 6.1 & 6.2 */
      use "C:\Dropbox\Allison\nlsy.dta", clear
      * Random effects
      sem (anti90 <- self90@c1 pov90@c2 black@c3 hispanic@c4 childage@c5 married@c6 gender@c7 momage@c8 momwork@c9 A@1) ///
          (anti92 <- self92@c1 pov92@c2 black@c3 hispanic@c4 childage@c5 married@c6 gender@c7 momage@c8 momwork@c9 A@1) ///
          (anti94 <- self94@c1 pov94@c2 black@c3 hispanic@c4 childage@c5 married@c6 gender@c7 momage@c8 momwork@c9 A@1), ///
          covstruct(_lexogenous,diagonal) cov(_lexogenous*_oexogenous@0) latent(A ) nocapslatent ///
          cov( e.anti90@e1 e.anti92@e1 e.anti94@e1) 
      est store m1
      * Fixed effects - Also Table 6.2, with covariances instead of correlations
      sem (anti90 <- self90@c1 pov90@c2 black@c3 hispanic@c4 childage@c5 married@c6 gender@c7 momage@c8 momwork@c9 A@1) ///
          (anti92 <- self92@c1 pov92@c2 black@c3 hispanic@c4 childage@c5 married@c6 gender@c7 momage@c8 momwork@c9 A@1) ///
          (anti94 <- self94@c1 pov94@c2 black@c3 hispanic@c4 childage@c5 married@c6 gender@c7 momage@c8 momwork@c9 A@1), ///
          covstruct(_lexogenous,diagonal) cov(_lexogenous*_oexogenous@0) latent(A ) nocapslatent ///
          cov( e.anti90@e1 e.anti92@e1 e.anti94@e1 ///
          A*(self90 pov90 self92 pov92 self94 pov94) )
      est store m2
      * Hybrid model
      sem (anti90 <- self90@c1 pov90@c2 black@c3 hispanic@c4 childage@c5 married@c6 gender@c7 momage@c8 momwork@c9 A@1) ///
          (anti92 <- self92@c1 pov92@c2 black@c3 hispanic@c4 childage@c5 married@c6 gender@c7 momage@c8 momwork@c9 A@1) ///
          (anti94 <- self94@c1 pov94@c2 black@c3 hispanic@c4 childage@c5 married@c6 gender@c7 momage@c8 momwork@c9 A@1), ///
          covstruct(_lexogenous,diagonal) cov(_lexogenous*_oexogenous@0) latent(A ) nocapslatent ///
          cov( e.anti90@e1 e.anti92@e1 e.anti94@e1 ///
          A*(pov90 pov92 pov94) )
      est store m3
      esttab m1 m2 m3, se(%8.3f)
      -------------------------------------------
      Richard Williams, Notre Dame Dept of Sociology
      StataNow Version: 18.5 MP (2 processor)

      EMAIL: [email protected]
      WWW: https://www3.nd.edu/~rwilliam

      Comment


      • #4
        I forgot, Jeremy Reynolds from Georgia nailed Table 6.3 a while back. See http://www.stata.com/statalist/archi.../msg00019.html

        When copying his code, you have to be careful of line breaks that show up online but that shouldn't be there in the do file. For convenience, here is his code, but you should read his post for an explanation:

        Code:
        use "http://www.statisticalhorizons.com/wp-content/uploads/occ.dta", clear
        
        #delimit ;
        sem (pf2 <- mdwgf1@c1 pf1@c2 FE@1 ERR1@1) // fixed effects and latent var (ERR1) to replace error term
            (pf3 <- mdwgf2@c1 pf2@c2 FE@1)
            (pf4 <- mdwgf3@c1 pf3@c2 FE@1),
            cov(e.pf2@0) // covariance of error term set to zero to remove it from the model
            cov(ERR1*_oexogenous@0 ERR1*FE@0 ERR1*mdwgf3) // ERR1 should only correlate with future values of cross-lagged IV
            nocapslatent latent(FE ERR1)
            method(mlmv);
        #delimit cr
        
        
        *Model 2 (2nd half of model)
        #delimit ;
        sem (mdwgf2 <- pf1@c1 mdwgf1@c2 FE@1 ERR1@1) // fixed effects and latent var (ERR1) to replace error term
            (mdwgf3 <- pf2@c1 mdwgf2@c2 FE@1)
            (mdwgf4 <- pf3@c1 mdwgf3@c2 FE@1),
            cov(e.mdwgf2@0) // covariance of error term set to zero to remove it from the model
            cov(ERR1*_oexogenous@0 ERR1*FE@0 ERR1*pf3) // ERR1 should only correlate with future values of cross-lagged IV
            nocapslatent latent(FE ERR1)
            method(mlmv);
        #delimit cr
        -------------------------------------------
        Richard Williams, Notre Dame Dept of Sociology
        StataNow Version: 18.5 MP (2 processor)

        EMAIL: [email protected]
        WWW: https://www3.nd.edu/~rwilliam

        Comment


        • #5
          These replies were really helpful and made me very happy. Thank you, Marcos, for your enthusiastic reply that encourages reading Stata’s books on sem (and for suggesting the re-registration, which I did promptly). Thank you, Richard, for providing the code in full detail. In fact, I was hoping for a reply from you, since I found many contributions from your hand on the Stata Forum on Allison's booklet.
          In my search process for more information regarding this issue I stumbled upon an item in Allison’s blog discussing causal inference on panel data (see http://www.statisticalhorizons.com/m...usal-inference). In this blog item, Allison refers to a manuscript that describes a simulation study in which Maximum Likelihood Estimation (MLE) for Dynamic Panel Models with Cross-Lagged effects is compared to the method of Generalized Method of Moments (GMM). The main text contains SAS code, while the appendix of the manuscript shows corresponding code for Stata’s sem, Mplus and the R package lavaan. The code is supplemented with an elaborate explanation, which clarified to me the presence of the ERR1 term in Jeremy Reynolds’ cod of Table 6.3, appearing to be a workaround for the fact that Stata’s sem command “does not allow the error term in an equation to be correlated with observed, exogeneous variables”.

          Kind regards, Adriaan Hoogendoorn

          Comment


          • #6
            A clear explanation of the ERR1 term in the code for Table 6.3 appears to be in the Stata List contribution by Jeremy Reynolds that Richard mentioned (but that I initially overread)

            Comment


            • #7
              May I ask a question on the cross-lagged fixed effects model? Thanks to this post, I could try the do-file created by professor Jeremy Reynolds. But a problem of mine is that I am using two-wave panel data and so the do-file did not work for my case; Stata generated an error message, "too many latent variables." When I dropped "ERR1" from the do-file, Stata produced an output that I cannot trust.

              Is there any way to conduct a cross-lagged fixed effects model with two-wave data using Stata?

              Best,

              Joonmo Son

              Comment


              • #8
                Joonmo:
                welcome to the list.
                The best way to get helpful replies is to start a new thread, as your query sounds different from Adriaan's one. Thanks.
                Kind regards,
                Carlo
                (StataNow 18.5)

                Comment


                • #9
                  I see and thanks, Carlo.

                  Comment


                  • #10
                    Hi Joonmo,

                    It has been quite a while since I have thought about these models, and I am not an expert on this topic.

                    My impression, however, is that while one can estimate a regular cross-lagged panel model with two waves of data (see for instance the little green Sage book by Finkel 1995), adding the fixed effects to the cross-lagged panel model requires at least three waves of data.

                    Allison's discussion of the topic (see the link below) does not seem to say this explicitly. However, he does write, "the assumption of sequential exogeneity is modeled by allowing the error term at each point in time to be correlated with future values of the time-dependent covariates" (page 5). Because the first error term appears at wave 2, there has to be a third wave of data to establish that correlation. The fact that Stata flags the reduced model with only two waves of data as unidentified because of too many latent variables seems consistent with this interpretation.

                    http://statisticalhorizons.com/wp-co...-Inference.pdf

                    Hope that helps,

                    Jeremy

                    Comment


                    • #11
                      Thanks for your great answer, Jeremy.

                      Comment


                      • #12
                        Reviving this old thread, in case anybody comes across it again -- in the book mentioned above, Allison mostly used Stata but switched to MPlus in Ch. 6 because at the time Stata could not estimate the Stuctural Equation Models he presented. His models can now be easily estimated with the xtdpdml command, available from SSC. xtdpdml is basically a shell for sem but makes the model specification process much easier and less error prone. The following code replicates his tables from Ch. 6:

                        Code:
                        * Replicate Allisons Table 6.1 using xtdpdml
                        use "http://www.statisticalhorizons.com/wp-content/uploads/nlsy.dta", clear
                        gen id = _n
                        reshape long anti pov self, i(id) j(year)
                        xtset id year, delta(2)
                        
                        * Table 6.1 - Random effects
                        xtdpdml anti self pov, inv(black hispanic childage married gender momage momwork) ylag(0) tfix errorinv re
                        est store re
                        
                        * Table 6.1 - Fixed effects
                        xtdpdml anti self pov, inv(black hispanic childage married gender momage momwork) ylag(0) tfix errorinv
                        est store fe
                        
                        * Table 6.1 - Compromise model. Have to zero out self correlations with Alpha
                        xtdpdml anti self pov, inv(black hispanic childage married gender momage momwork) ylag(0) tfix errorinv ///
                            semopts(cov(Alpha*(self1 self2 self3)@0 ))
                        est store compromise
                        
                        * Try to replicate Allison's Table 6.2. Last part of output reproduces Z values shown by
                        * Allison but I can't figure out how to reproduce the correlations he reported.
                        * But Z values are the most important anyway.
                        est restore fe
                        sem
                        
                        * Replicate Allison's Table 6.3 using xtdpdml
                        use "http://www.statisticalhorizons.com/wp-content/uploads/occ.dta", clear
                        gen id = _n
                        reshape long pf mdwgf, i(id) j(j)
                        xtset id j
                        * Median Wage
                        xtdpdml mdwgf, pre(L.pf)
                        * Proportion female
                        xtdpdml pf, pre(L.mdwgf)
                        -------------------------------------------
                        Richard Williams, Notre Dame Dept of Sociology
                        StataNow Version: 18.5 MP (2 processor)

                        EMAIL: [email protected]
                        WWW: https://www3.nd.edu/~rwilliam

                        Comment


                        • #13
                          First of all, sorry by pushing this quite old topic. However, I have a question directly concerning the issue discussed here, basically the thread's topic.
                          Maybe the xtdpdml package offers this but I am not able to reproduce it.

                          I would like to estimate a simple IV model with more than one endogenous variable using fixed effects.
                          The xtivreg or xtivreg2 commands do offer this, but I would like to specify the first stage regression by myself.

                          Basicyally, consider the following simple example:

                          y is to be explained
                          x1 is strictly exogenous;
                          x2 and x3 are endogenous;
                          x4 and x5 are exogenous instruments
                          Code:
                          xtivreg y x1 (x2 x3 = x4 x5), first vce(robust)
                          This leads to x2 and x3 being predicted using x4, x5 and x1. However, I want x4 as an instrument for x2 and x5 as an instrument for x3.
                          This can be done using reg3:
                          Code:
                          reg3 (y x1 x2 x3) (x2 x4 x1) (x3 x5 x1), 2sls
                          reg3 unfortunately does not offer rubust standard errors of fixed effects. So this does not do the job.
                          Another possibility is to estimate the thing as a structural model using sem:
                          Code:
                          sem (y <- x1 x2 x3) (x2 <- x4 x1) (x3 <- x5 x1), vce(robust) cov(e.y*e.x2) cov(e.y*e.x3)
                          which basically produces the same second stage results as ivreg when we specify the equations accordingly.
                          Here we cannot use fixed effects which brings us back to the topic.

                          So I would like to know if xtdpdml allows us to estimate a simple IV model with fixed effects and custom specification of the first stage regression. I do not see this option in the package descriptions even though it should cover all sem estimations.

                          Comment


                          • #14
                            xtdpdml does not have this built-in. You can output the stata code it generates and then try tweaking by hand.
                            -------------------------------------------
                            Richard Williams, Notre Dame Dept of Sociology
                            StataNow Version: 18.5 MP (2 processor)

                            EMAIL: [email protected]
                            WWW: https://www3.nd.edu/~rwilliam

                            Comment


                            • #15
                              Thank you, I was expecting something like that.

                              So can you tell me how to rebuild a simple fixed effects model using xtdpdml?
                              If we can manage this we can use the equivalent sem code to build a customizable xtivreg, which is pretty nice I think.

                              I am trying try to reproduce
                              Code:
                              xtset id t
                              xtreg y x, fe
                              and ended up with
                              Code:
                              xtdpdml y x, show ylag(0)
                              yielding the corresponding sem code using the show option
                              Code:
                              reshape wide y x, i(id) j(t)
                              sem (y1 <- x1@b1 Alpha@1 ) (y2 <- x2@b1 Alpha@1 ) (y3 <- x3@b1 Alpha@1 ), var(Alpha) iterate(250) technique(nr 25 bhhh 25) noxconditional
                              in case of T=3.

                              So I thought the Alphas should capture the fixed effects as explained in the xtdpdml help file and the point estimate of x on y should be the simple FE estimator.
                              Unfortunately the estimates are not equivalent when I test it using the dataset from the help file example: https://www3.nd.edu/~rwilliam/statafiles/wages

                              I would appreciate a comment.

                              Comment

                              Working...
                              X