Latent Curve Model with Structured Residuals

585 views
Skip to first unread message

kar...@cornell.edu

unread,
Mar 29, 2017, 9:22:27 PM3/29/17
to lavaan
Hi all,

I'm attempting to test a multivariate latent curve model with structured residuals (LCM-SR) as proposed by Curran et al. (2014) here. Specifically, I'm trying to recreate Figure 7 (here) for two variables across four waves. While I have the growth curves built, I'm running into a lot of difficulty coding the structured residuals and the lags needed to test the bidirectional influence of one construct on the other over time.

Curran has MPlus input for this model posted on his website available for download. I have never used MPlus before, so seeing this code was little help. I attempted to use the mplus2lavaan function, but could not get past an error.

Any help coding this model would be so greatly appreciated! 

Thanks,
Kaylin

Terrence Jorgensen

unread,
Mar 30, 2017, 5:56:25 AM3/30/17
to lavaan
 have never used MPlus before, so seeing this code was little help. I attempted to use the mplus2lavaan function, but could not get past an error.

Posting the path model is a big help, so if you can post your attempt at lavaan model syntax, someone here could give you some feedback.  Regarding translating from Mplus to lavaan:
  • BY is the same operator as lavaan's =~
  • WITH is the same operator as lavaan's ~~
  • ON is the same operator as lavaan's ~
  • intercepts in Mplus are specified not as regressing in a constant (X ~ 1) but by putting a variable name in brackets: [X]
  • Mplus labels parameters after instead of before: Factor BY X1 (label1)   instead of Factor =~ label1*X1
  • Mplus fixes parameters with @ instead of *, also after instead of before: Factor BY X1@1 (instead of Factor =~ 1*X1)
If you attach the file with the Mplus model in a post that also includes your syntax that led to the mplus2lavaan() error, someone might be able to find the problem.

Terrence D. Jorgensen
Postdoctoral Researcher, Methods and Statistics
Research Institute for Child Development and Education, the University of Amsterdam

Message has been deleted

kar...@cornell.edu

unread,
Mar 30, 2017, 3:05:45 PM3/30/17
to lavaan
(Sorry, I posted this once and noticed a few typos - going to try this again)

Here is the model so far, and I'm wondering how to include the residual structure. Are "phantom variables," as seen in Curran's example input (attached), needed?:

modelaltxy <- '
# growth curve rail
i =~ rail1 + 1*rail2 + 1*rail3 + 1*rail4
i ~ 1; i ~~ i
s= ~ rail1 + 1*rail2 + 2*rail3 + 3*rail4
s ~ 1; s ~~ s
rail1 ~~ rail1
rail2 ~~ rail2
rail3 ~~ rail3
rail4 ~~ rail4

# autoregressive components rail
rail2 ~ a1*rail1
rail3 ~ a2*rail2
rail4 ~ a3*rail3

# growth curve dep
i2 =~ dep1 + 1*dep2 + 1*dep3 + 1*dep4
i2 ~ 1; i2 ~~ i2
s2= ~ dep1 + 1*dep2 + 2*dep3 + 3*dep4
s2 ~ 1; s2 ~~ s2
dep1 ~~ dep1
dep2 ~~ dep2
dep3 ~~ dep3
dep4 ~~ dep4

# autoregressive components dep
dep2 ~ b1*dep1
dep3 ~ b2*dep2
dep4 ~ b3*dep3

# cross-lagged components
dep3 ~ rail2
dep4 ~ rail3
rail3 ~ dep2
rail4 ~ dep3
'

fit.altxy <- lavaan(modelaltxy, sample.cov = COV, sample.mean = MEANS,
                    sample.nobs = 180, mimic = "EQS", missing = "fiml")
summary(fit.altxy)



Also, thank you for the translation - Curran's Mplus code seems slightly less foreign now. Speaking of which, I have attached here his demo data and Mplus input example. After loading lavaan and setting my working directory to where these two Curran files are located, here is what I'm attempting to run for the mplus2lavaan() function:

out <- mplus2lavaan("M06.inp")
summary(out$lav.out)

Seems like it should be easy enough, but I receive this error:

Read 80 items
Error in parse(text = x, keep.source = FALSE) : 
  <text>:2:0: unexpected end of input
1: ~ 
   ^

Thank you again for any help,
Kaylin
currandemo.dat
M06.inp

Terrence Jorgensen

unread,
Apr 1, 2017, 10:05:10 AM4/1/17
to lavaan
Here is the model so far, and I'm wondering how to include the residual structure. Are "phantom variables," as seen in Curran's example input (attached), needed?:

Yes, you can do that like this:

e.rail1 =~ 1*rail1
rail1
~~ 0*rail1
e
.rail1 ~~ NA*e.rail1

e
.rail2 =~ 1*rail2
rail2
~~ 0*rail2
e
.rail2 ~~ NA*e.rail2

e
.rail2 ~ e.rail1
...

But I think it should not be necessary because lavaan will kind of make phantom latents automatically if you just include structural paths among residuals.  So they way you already have it should work.

rail2 ~ a1*rail1

Nothing wrong with trying it both ways, if you want to be sure and get some exercise experimenting with lavaan.

out <- mplus2lavaan("M06.inp")
summary(out$lav.out)

Seems like it should be easy enough, but I receive this error:

Read 80 items
Error in parse(text = x, keep.source = FALSE) : 
  <text>:2:0: unexpected end of input
1: ~ 
   ^

I'm not sure exactly what that error means, but I do not expect the direct translation from Mplus to lavaan to work in this instance.  In lavaan, you can only create new parameters that are functions of other parameters.  That is what Mplus is doing, but the "new(kappa)" utility is just not available in lavaan, as far as I know.  I think you can get the desired result by translating this part of Mplus syntax:

 model constraint:           ! defining model constraint on alc predicting dep over time;
  new(kappa);                       ! create "kappa" that corresponds to Eq 17 in paper;
  deponalc3= deponalc2 + 1*kappa;   ! kappa serves to increment value of lagged effect;
  deponalc4= deponalc2 + 2*kappa;   ! with each unit-passage of time;
  deponalc5= deponalc2 + 3*kappa;

to look like this in lavaan, which just rearranges terms with some algebra, explicitly defines kappa, then constraints it:

kappa := deponalc3 - deponalc2
kappa
== (deponalc4 - deponalc2) / 2
kappa
== (deponalc5 - deponalc2) / 3

I think you used different parameter labels, so just update those.  I am unsure whether it is OK to constrain "kappa" twice, like I do above, but hopefully that works.  If not, you could create three kappas and constrain them to be equal.

kappa1 := deponalc3 - deponalc2
kappa2
:= (deponalc4 - deponalc2) / 2
kappa3
:= (deponalc5 - deponalc2) / 3
kappa1
== kappa2
kappa1
== kappa3

kar...@cornell.edu

unread,
Apr 2, 2017, 9:14:21 PM4/2/17
to lavaan
Hi Terrence,

Thank you for your suggestions! Over the next few days, I'm going to try to work with the guidance you've provided here. If I hit any roadblocks, I'll report back. Thanks again for your help!

Best,
Kaylin
Reply all
Reply to author
Forward
0 new messages