Multigroup path analysis issue: Unable to constrain regressions to equality for one out of my four groups

312 views
Skip to first unread message

William

unread,
May 22, 2020, 10:20:23 PM5/22/20
to lavaan

Hey, lavaan masters! First time posting in this community. I'm conducting multigroup path analysis with a model in which the relationships between three predictors and one outcome are mediated (in parallel) by 3 other variables. I'm running into an issue where the regression parameters for one of my four groups aren't constrained to equality unlike those of the other groups. What could be the issue? Below is my script (let me know if there's anything else wrong with my script—even if unrelated to this inquiry). Additionally, if anyone knows how to make these analyses run faster, please let me know. Last time I ran these analyses, it took around 6 hours (doesn't look too good for when I have to sequentially release the constraints...); granted, I have 300k+ respondents, so I guess it isn't too surprising (is there any way to use more than just one of my device's cores? I'm a total R newbie).


Model.2 <- ' Outcome ~ b1 * M1 + b2 * M2 + b3 * M3 + b4 * M4 + b5 * M5 + b6 * M6 + c1 * P1 + c2 

                * P2 + c3 * P3

                

           M1 ~ a1 * P1 + a2 * P2 + a3 * P3

           M2 ~ a4 * P1 + a5 * P2 + a6 * P3

           M3 ~ a7 * P1 + a8 * P2 + a9 * P3

           M4 ~ a10 * P1 + a11 * P2 + a12 * P3

           M5 ~ a13 * P1 + a14 * P2 + a15 * P3

           M6 ~ a16 * P1 + a17 * P2 + a18 * P3

           

           ab1 := a1*b1

           ab2 := a2*b1

           ab3 := a3*b1

           ab4 := a4*b2

           ab5 := a5*b2

           ab6 := a6*b2

           ab7 := a7*b3

           ab8 := a8*b3

           ab9 := a9*b3

           ab10 := a10*b4

           ab11 := a11*b4

           ab12 := a12*b4

           ab13 := a13*b5

           ab14 := a14*b5

           ab15 := a15*b5

           ab16 := a16*b6

           ab17 := a17*b6

           ab18 := a18*b6

           

           total := c1 + c2 + c3 + ab1 + ab2 + ab3 + ab4 + ab5 + ab6 + ab7 + ab8 + ab9 + ab10 + ab11 + ab12 + ab13 + ab14 + ab15 + ab16 +           ab17 + ab18 '

 

SEM.2 <- sem(Model.2, data = data_df, group = "GROUP", group.equal = c("regressions"), se = "bootstrap", bootstrap = 5000)

summary(SEM.2, standardized=F, fit=T, rsquare=T)

parameterestimates(SEM.2, boot.ci.type="bca.simple", standardized = T)

modindices(SEM.2, sort.=T)


Thanks! 

William

unread,
May 22, 2020, 10:47:05 PM5/22/20
to lavaan
*6 mediators—not 3 (whoops)

Terrence Jorgensen

unread,
May 24, 2020, 6:25:39 AM5/24/20
to lavaan

the regression parameters for one of my four groups aren't constrained to equality unlike those of the other groups. What could be the issue?


You are only providing one label per parameter, as though it were a single-group model.  To apply the same label across 4 groups (thus, constraining it to equality, so the group.equal= argument is unnecessary), provide a vector of labels (one per group).

Outcome ~ c(b1, b1, b1, b1)*M1

This method provides way more options than the group.equal= argument anyway, like fitting partial constraints, e.g., this constraints the slope to equality for groups 1 and 4, which can differ from groups 2 and 3 (whose slopes are equal):

Outcome ~ c(b1, b2, b2, b1)*M1


if anyone knows how to make these analyses run faster, please let me know ... I have 300k+ respondents


With an asymptotically large sample, I think you can safely rely on the default delta-method SEs instead of bootstrapping.  Or you could use the Monte Carlo approach, which doesn't require fitting the model 5000 times (only once, then resample parameters instead of subjects, which takes seconds instead of hours).  It is easily implemented in the semTools package.  See the ?monteCarloMed help-page examples for using it with lavaan objects.

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

William

unread,
May 27, 2020, 1:27:58 PM5/27/20
to lavaan
Thank you for responding—worked perfectly (and quickly without the bootstrapping!). I totally forgot about manually coding the constraints in the model (something I've done successfully not too long ago). This might be a follow-up question more appropriate for SEMNET, but I'll ask anyway: How would you go about comparing regression coefficients across groups? This is my first time doing multigroup path analysis with more than 2 groups. When I free a constraint across all 4 groups and my model fit significantly improves, would the next step then be pairwise comparisons—what would that look like?

Terrence Jorgensen

unread,
May 29, 2020, 4:16:19 AM5/29/20
to lavaan
How would you go about comparing regression coefficients across groups? This is my first time doing multigroup path analysis with more than 2 groups. When I free a constraint across all 4 groups and my model fit significantly improves, would the next step then be pairwise comparisons—what would that look like?

If your slopes are all labeled in your unconstrained model, you could use Wald tests:

?lavTestWald

You could also define new parameters in your syntax, one for each pairwise comparison (i.e., difference between slopes).

William

unread,
Jun 5, 2020, 11:15:35 AM6/5/20
to lavaan
I'm having trouble implementing your recommendations regarding Wald tests and defining parameters. Could you please share any resources on how to do multigroup path analysis with > 2 groups?

Thank you!

Terrence Jorgensen

unread,
Jun 5, 2020, 4:52:45 PM6/5/20
to lavaan
I'm having trouble implementing your recommendations regarding Wald tests and defining parameters. 

You label the parameters relevant to your hypotheses, then type out constraints that represent corresponding null hypotheses. 

fit <- sem('Outcome ~ c(b1, b2, b3, b4)*M1', ...)
## hypothesize that all slopes are equal?
omnibusH0
<- c('b1 == b2','b1 == b3','b1 == b4')
lavTestWald
(fit, omnibusH0)
## define parameters for each difference
diffs
<- '
diff12 := b1 - b2
diff13 := b1 - b3
...
dif34 := b3 - b4
'

fit1
<- update(fit, model = c('Outcome ~ c(b1, b2, b3, b4)*M1', diffs))
summary
(fit)

Patrick (Malone Quantitative)

unread,
Jun 5, 2020, 6:52:38 PM6/5/20
to lav...@googlegroups.com
Terrence,

I'm also just learning about how to use update() . Just to make sure I follow, should the last line have been summary(fit1) ?

Thanks.

--
You received this message because you are subscribed to the Google Groups "lavaan" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lavaan+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/lavaan/024f3d3d-5a5d-4838-b2f4-1154b8bfafc2o%40googlegroups.com.


--
Patrick S. Malone, Ph.D., Malone Quantitative
NEW Service Models: http://malonequantitative.com

He/Him/His

Terrence Jorgensen

unread,
Jun 12, 2020, 4:49:31 AM6/12/20
to lavaan
should the last line have been summary(fit1) ?

Woops, yes!
Reply all
Reply to author
Forward
0 new messages