Predictors at within-level in LCM-SR

112 views
Skip to first unread message

Ingvild Finsrud

unread,
Nov 2, 2022, 4:32:43 AM11/2/22
to lavaan
Hi everyone!
Does anyone here have experience with adding time-invariant predictors (such as dummy variable for treatment condition) at the within-level in LCM-SR models?
Someone has suggested the following to me: just adding the predictor on the residuals along with the cross-lags (the red is the predictor added as constrained over time (the syntax is from Curran et al., 2014):

# DEPRESSION
sdep2 ~ p3*sdep1 + p5*salc1 + p6*x 
sdep3 ~ p3*sdep2 + p5*salc2 + p6*x
sdep4 ~ p3*sdep3 + p5*salc3s + p6*x
sdep5 ~ p3*sdep4 + p5*salc4 + p6*x

I have also seen the following syntax (From an article Orth et al., 2021), where they do something similar, adding the predictor as constrained over time :

#### LCM-SR (tic as constant effect) 
#### lcmsr_tic.mod <- ' 
# Define intercept and growth factors 
ix =~ 1*sat6.1 + 1*sat6.2 + 1*sat6.3 + 1*sat6.4 
iy =~ 1*log_inc.1 + 1*log_inc.2 + 1*log_inc.3 + 1*log_inc.4 
sx =~ 0*sat6.1 + 1*sat6.2 + 2*sat6.3 + 3*sat6.4 
sy =~ 0*log_inc.1 + 1*log_inc.2 + 2*log_inc.3 + 3*log_inc.4 

  # Define phantom latent variables 
etax1 =~ 1*sat6.1 
etax2 =~ 1*sat6.2 
etax3 =~ 1*sat6.3 
etax4 =~ 1*sat6.4 

etay1 =~ 1*log_inc.1 
etay2 =~ 1*log_inc.2 
etay3 =~ 1*log_inc.3 
etay4 =~ 1*log_inc.4 

  # Autoregressive effects 
etax2 ~ a1*etax1 
etax3 ~ a1*etax2 
etax4 ~ a1*etax3 
etay2 ~ a2*etay1 
etay3 ~ a2*etay2 
etay4 ~ a2*etay3 

  # Crosslagged effects 
etay2 ~ c1*etax1 
etay3 ~ c1*etax2 
etay4 ~ c1*etax3 

etax2 ~ c2*etay1 
etax3 ~ c2*etay2 
etax4 ~ c2*etay3 

  # Some further constraints on the variance structure 
# 1. Set error variances of the observed variables to zero 
sat6.1 ~~ 0*sat6.1 
sat6.2 ~~ 0*sat6.2 
sat6.3 ~~ 0*sat6.3 
sat6.4 ~~ 0*sat6.4 

log_inc.1 ~~ 0*log_inc.1 
log_inc.2 ~~ 0*log_inc.2 
log_inc.3 ~~ 0*log_inc.3 
log_inc.4 ~~ 0*log_inc.4 
  # 2. Let lavaan estimate the variance of the latent variables 
etax1 ~~ varx1*etax1 
etax2 ~~ varx2*etax2 
etax3 ~~ varx3*etax3 
etax4 ~~ varx4*etax4 

etay1 ~~ vary1*etay1 
etay2 ~~ vary2*etay2 
etay3 ~~ vary3*etay3 
etay4 ~~ vary4*etay4 

  # 3. We also want estimates of the intercept factor variances, the slope 
# variances and the different covariances 
ix ~~ varix*ix 
iy ~~ variy*iy 

sx ~~ varsx*sx 
sy ~~ varsy*sy 

ix ~~ covi*iy 
ix ~~ covixsx*sx 
ix ~~ covixsy*sy 

iy ~~ coviysx*sx 
iy ~~ coviysy*sy 

sx ~~ covs*sy 

# 4. We have to define that the covariance between the intercepts and 
# the slopes and the latents of the first time point are zero 
etax1 ~~ 0*ix 
etay1 ~~ 0*ix 
etax1 ~~ 0*sx 
etay1 ~~ 0*sx 
etax1 ~~ 0*iy 
etay1 ~~ 0*iy 
etax1 ~~ 0*sy 
etay1 ~~ 0*sy 

  # 5. Finally, we estimate the covariance between the latents of x and y 
# of the first time point, the second time-point and so on. note that 
# for the second to fourth time point the correlation is constrained to 
# the same value 
etax1 ~~ cov1*etay1 
etax2 ~~ cove*etay2 
etax3 ~~ cove*etay3 
etax4 ~~ cove*etay4 

  # The model also contains a mean structure and we have to define some 
# constraints for this part of the model. we estimate the interecepts # of the time point-specific manifest variable and constrain the 
# mean of the intercept and slope factors to 0 
sat6.1 ~ 0*1 
sat6.2 ~ 0*1 
sat6.3 ~ 0*1 
sat6.4 ~ 0*1 
  log_inc.1 ~ 0*1 
log_inc.2 ~ 0*1 
log_inc.3 ~ 0*1 
log_inc.4 ~ 0*1 
  etax1 ~ 0*1 
etax2 ~ 0*1 
etax3 ~ 0*1 
etax4 ~ 0*1 
  etay1 ~ 0*1 
etay2 ~ 0*1 
etay3 ~ 0*1 
etay4 ~ 0*1 
  ix ~ 1 iy ~ 1 
sx ~ 1 sy ~ 1 
  
# incorporating tic 
etax1 + etax2 + etax3 + etax4 ~ ticx*sex_gen 
etay1 + etay2 + etay3 + etay4 ~ ticy*sex_gen 
  sex_gen ~~ sex_gen 

  # define correlations for CI 
cori := covi / (sqrt(varix) * sqrt(variy)) 
cors := covs / (sqrt(varsx) * sqrt(varsy)) 
corixsx := covixsx / (sqrt(varix) * sqrt(varsx)) 
corixsy := covixsy / (sqrt(varix) * sqrt(varsy)) 
coriysx := coviysx / (sqrt(variy) * sqrt(varsx)) 
coriysy := covixsx / (sqrt(variy) * sqrt(varsy)) 
  cort1 := cov1 / (sqrt(varx1) * sqrt(vary1)) 
cort2 := cove / (sqrt(varx2) * sqrt(vary2)) 
cort3 := cove / (sqrt(varx3) * sqrt(vary4)) 
cort4 := cove / (sqrt(varx4) * sqrt(vary4)) 

' lcmsr_tic.fit <- sem(lcmsr_tic.mod, missing = "fiml", data = pf, verbose = T) capture.output(summary(lcmsr_tic.fit, fit.measures = T, std = T, ci = T), file = "./results/TIC/LCM-SR.txt")

My questions are: these two ways of adding TICs to within-level in LCM-SR are slightly different, where the syntax from Orth includes a covariance specification between the TIC "sex_gen ~~ sex_gen". So the two different ways of adding the predictor in my case, gives slightly different results. Can anyone explain what the difference between these two approaches mean? 
AND: In my study the predictor I want to add at the within-patient level  is a dummy variable for treatment condition. The LCM-SR model is built so that it investigates 3 variables: emotional clarity, rumination and symptom distress. So before I add treatment condition here is my syntax for the cross-lagged effects:

# RUM # 
sRUM2 ~ p2*sRUM1 + p4*sPHQ_ADS2 + p7*sUA1
sRUM3 ~ p2*sRUM2 + p4*sPHQ_ADS3 + p7*sUA2
sRUM4 ~ p2*sRUM3 + p4*sPHQ_ADS4 + p7*sUA3
sRUM5 ~ p2*sRUM4 + p4*sPHQ_ADS5 + p7*sUA4
sRUM6 ~ p2*sRUM5 + p4*sPHQ_ADS6 + p7*sUA5
sRUM7 ~ p2*sRUM6 + p4*sPHQ_ADS7 + p7*sUA6
sRUM8 ~ p2*sRUM7 + p4*sPHQ_ADS8 + p7*sUA7
sRUM9 ~ p2*sRUM8 + p4*sPHQ_ADS9 + p7*sUA8
sRUM10 ~ p2*sRUM9 + p4*sPHQ_ADS10 + p7*sUA9
sRUM11 ~ p2*sRUM10 + p4*sPHQ_ADS11 + p7*sUA10
sRUM12 ~ p2*sRUM11 + p4*sPHQ_ADS12 + p7*sUA11

# PHQ_ADS #
sPHQ_ADS2 ~ p3*sPHQ_ADS1 + p5*sRUM1 + p6*sUA1
sPHQ_ADS3 ~ p3*sPHQ_ADS2 + p5*sRUM2 + p6*sUA2
sPHQ_ADS4 ~ p3*sPHQ_ADS3 + p5*sRUM3 + p6*sUA3
sPHQ_ADS5 ~ p3*sPHQ_ADS4 + p5*sRUM4 + p6*sUA4
sPHQ_ADS6 ~ p3*sPHQ_ADS5 + p5*sRUM5 + p6*sUA5
sPHQ_ADS7 ~ p3*sPHQ_ADS6 + p5*sRUM6 + p6*sUA6
sPHQ_ADS8 ~ p3*sPHQ_ADS7 + p5*sRUM7 + p6*sUA7
sPHQ_ADS9 ~ p3*sPHQ_ADS8 + p5*sRUM8 + p6*sUA8
sPHQ_ADS10 ~ p3*sPHQ_ADS9 + p5*sRUM9 + p6*sUA9
sPHQ_ADS11 ~ p3*sPHQ_ADS10 + p5*sRUM10 + p6*sUA10
sPHQ_ADS12 ~ p3*sPHQ_ADS11 + p5*sRUM11 + p6*sUA11 

# UA #
sUA2 ~ p1*sUA1 + p9*sRUM1 + p8*sPHQ_ADS2
sUA3 ~ p1*sUA2 + p9*sRUM2 + p8*sPHQ_ADS3
sUA4 ~ p1*sUA3 + p9*sRUM3 + p8*sPHQ_ADS4
sUA5 ~ p1*sUA4 + p9*sRUM4 + p8*sPHQ_ADS5
sUA6 ~ p1*sUA5 + p9*sRUM5 + p8*sPHQ_ADS6
sUA7 ~ p1*sUA6 + p9*sRUM6 + p8*sPHQ_ADS7
sUA8 ~ p1*sUA7 + p9*sRUM7 + p8*sPHQ_ADS8
sUA9 ~ p1*sUA8 + p9*sRUM8 + p8*sPHQ_ADS9
sUA10 ~ p1*sUA9 + p9*sRUM9 + p8*sPHQ_ADS10
sUA11 ~ p1*sUA10 + p9*sRUM10 + p8*sPHQ_ADS11
sUA12 ~ p1*sUA11 + p9*sRUM11 + p8*sPHQ_ADS12 

What I really want to find out is whether treatment condition interacts with pathways of these variables. For instance, I wonder whether rumination is predictive of symptom distress only in one of the treatment conditions. Looking at my output (when I add the predictor at the within-level) I am uncertain whether this way of adding the predictor is the right way (i.e I am not sure the output can tell me about the things I want to know). So question 2 would be: how do we interpret the results of a dummy variable which does not change over measurement time-points when we add it to the within-level/structured residuals?

And last questions: I have seen debates regarding random intercept models where people suggest to add such predictors only at the between level (slope and intercept). Do anyone have opinions on what is appropriate in this case?

ANY thoughts/input on (or experience with) how to handle predictors at within-level/between-level in LCM-SR are very welcome :)

Ingvild

Ingvild Finsrud

unread,
Nov 2, 2022, 4:50:14 AM11/2/22
to lavaan
I am just including this, just in case I did not explain well enough what I want to examine: In multilevel modeling I know how the following can be done (and this is what I want to do in the LCM-SR model):

"Specifically, because MLM separates the random effects into two parts (between-subject random effects and within-subject random errors), MLM allows for the examination of new effects of interest such as cross-level interaction effects. For example, researchers can examine how treatment condition (and other between-subject level predictor) influences the individual growth trajectories (within-subjects repeated measures) of research participants over time."

So I wonder: can we examine this - cross-level interaction effects - in LCM-SR by adding the treatment conditions as predictor on the residuals along with the cross-lags? Or do we "ask" the syntax to answer something totally different when we do this? And if the way I am doing it is wrong, does anyone know if there is a way to do this in LCM-SR?

Thanks again,
Ingvild :)

Terrence Jorgensen

unread,
Nov 7, 2022, 4:38:10 AM11/7/22
to lavaan
these two ways of adding TICs to within-level in LCM-SR are slightly different, where the syntax from Orth includes a covariance specification between the TIC "sex_gen ~~ sex_gen". So the two different ways of adding the predictor in my case, gives slightly different results. Can anyone explain what the difference between these two approaches mean? 

I think you are conflating different issues.  These should provide equivalent results, given the constraints that make eta1-eta4 the latent-space equivalents of sat6.1-sat6.4

This has nothing to do with explicitly estimating the exogenous variance (sex_gen ~~ sex_gen), which you could do in the top approach as well.  In neither case is it necessary because lavaan will simply treat its observed summary statistics as fixed (see fixed.x=TRUE in ?lavOptions).  

You can specify it both ways to check that results are equivalent.  Maybe just do so in a smaller 2-occasion model for one of the variables, so it is easier to find what you are looking for.

What I really want to find out is whether treatment condition interacts with pathways of these variables.

Pathways are parameters, not variables.  Do you mean you want to allow the paths to be moderated by treatment?  Then you want to run a multigroup SEM instead of using treatment as an exogenous predictor.  
 
how do we interpret the results of a dummy variable which does not change over measurement time-points when we add it to the within-level/structured residuals?

An exogenous predictor's effect would only be its "main" effect, not an interaction.  Allowing that effect to vary over time would imply that the treatment effect is moderated by time, but that does not sound like the interaction you are looking for.

And last questions: I have seen debates regarding random intercept models where people suggest to add such predictors only at the between level (slope and intercept). Do anyone have opinions on what is appropriate in this case?

It would be equivalent to do so, when your TIC's effect is constrained to equality over time.  In a model where the TIC affects the random intercept, the TIC's effect on time-specific indicators becomes an indirect effect via the (mediating) random intercept.  But all those loadings on the intercept are 1, so you should get the same estimates either way.  Regressing each time-specific variable on a TIC is only necessary when you want to allow moderation of its effect by time.

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

Ingvild Finsrud

unread,
Nov 7, 2022, 4:57:29 AM11/7/22
to lavaan
Thank you, Terrence, for clearing up my confusion. Very helpful!
It seems multigroup SEM is one solution, or to use an MNLFA-life nonlinear constraint, as described in Curran et al 2014. 

Ingvild

Terrence Jorgensen

unread,
Nov 7, 2022, 5:16:26 AM11/7/22
to lavaan
or to use an MNLFA-life nonlinear constraint

Yes, but that would require SAS, Mplus, or OpenMx. 


I'm surprised no one has tried it use MCMC, but that would be possible too, if you want to manually code your model in JAGS or Stan.
Reply all
Reply to author
Forward
0 new messages