Multi-group analysis; model syntax and on calculating effects from two groups

582 views
Skip to first unread message

Tim Duclos

unread,
Dec 3, 2016, 2:01:01 PM12/3/16
to lavaan
Greetings;

I am trying to run a multi-group analysis in order to test for a difference between year 1 (i.e. group 1) and year 2 (i.e. group 2).  Moreover, i wish to calculate effects that represent a joint product (i.e. a single value representing the effect) of the path values (for each path in the causal model respectively) across the two groups.  In my mind, using multi-group analysis, I seek to describe the effects (direct or indirect effects) that represent a single parameterization of the effects across both years (i.e. the groups) from a standard structural model.  Further, I know that I can also test for difference between year 1 and year 2 (i.e. a year effect) by comparing the fit of constrained vs. unconstrained models.  

But what I am confused about is exactly what I need to do to specify such a multi-group model as well as specify the calculation of the constrained direct or indirect effects thereof.  Contained at the bottom is my model syntax.  I know that if you only specify a single parameter label for a regression (ex: y~a*x) then you are by default constraining the regression coefficient (a) to equality between both groups in the multi-group model.  However, in the documentation http://lavaan.ugent.be/tutorial/groups.html  it seems to me to say that you can label the regression coefficients the same (i.e. just y~a*x, versus y~c(a1,a2)*x ) yet still allow all parameters to be free between group models if you simply omit the "group.equal=" argument when fitting the model.  Thus,  please, can anybody confirm that by fitting the following model (see model syntax at bottom) using the following fit function, I am allowing all parameters to be freely estimated in each group model:

fit.all <- sem(SEM.1, data = data.sem, estimator="MLM", group= "year")  #allow all parameters to be freely estimated in each group, respectively. 

And, conversely, again using the same model syntax (at bottom of post) if I now wish to constrain just the regression parameters to be equal between both groups I can run the following:

fit.all <- sem(SEM.1, data = data.sem, estimator="MLM", group= "year", group.equal="regressions")  #constrain regression parameters between both groups.

LASTLY-  when I fit a multi-group model constraining regression parameters to equality between groups, HOW are the direct and indirect effects calculated from these constrained parameters?  When I run the models that I describe here, the resulting calculated direct and indirect effects of the multi-group analysis where by I constrain regression parameters to equality between the two groups, i.e:

fit.all <- sem(SEM.1, data = data.sem, estimator="MLM", group= "year", group.equal="regressions")  #constrain regression parameters between both groups.

results in calculated direct and indirect effects exactly equal to the path parameters (i.e. the path coefficients) from the group1 model.  Thus, if I was to report such effects, while I claim to be constraining effects to equality between two groups, I am still only reporting effects calculated for group 1.  Nowhere in the model output do I see parameter values that have been constrained to equality between group 1 and group 2.  Again, my hope in running this multi-group analysis is to identify path values that represent the joint product (i.e. joint effect) from path values constrained to equality across both groups.   In other words, my goal in this analysis is to be able to report effects that represent the path coefficients parameterized to equality from two groups, not effects for each group parameterized separately.  Alas, isn't that the point of multi-group analysis?  

Any help is extremely appreciated!  Please!





SEM.1<-
  '
### 
#direct effect of mean temp
bird_N ~ m*t.mean

#direct effect of precip
bird_N ~ q*precip

###
#indirect effect of mean temp, via pc1.both
pc1.both ~ a*t.mean
bird_N ~ k*pc1.both

#indirect effect of precip, via pc1.both
pc1.both ~ e*precip


###
#indirect effect of mean temp, via pc2.both
pc2.both ~ f*t.mean + t.mean.sq  #quadratic effect placed here
bird_N ~ l*pc2.both

#indirect effect of precip, via pc2.both
pc2.both ~ j*precip + precip.sq  #quadratic effect placed here


### Specification of path values below:

#direct effect of mean t on bird
DE_t.mean:= m

#direct effect of precip 
DE_precip:= q

#total direct effect of climate (temp and precip)
TDE_climate:=  m + q


###
#indirect effect of mean t, via pc1.both
IE_t.mean_pc1:= k*a

#indirect effect of precip, via pc1.both
IE_precip_pc1:= k*e

#total indirect effect of climate via pc1.both
TIE_climate_pc1:= (a*k)+(e*k)

###
#indirect effect of mean t via pc2.both
IE_t.mean_pc2:= f*l

#indirect effect of precip via pc2.both
IE_precip_pc2:= j*l

#total indirect effect of climate via pc2.both
TIE_climate_pc2:= (f*l)+(j*l)


####

#total indirect effect of t via veg (both pc1 and pc2)
TIE_t:= (a*k) + (f*l)

#total indirect effect of precip 
TIE_p:= (e*k) + (j*l)

#total indirect effect of climate via veg (both pc1 and pc2)
TIE_climate:= ((a*k)+(e*k))  +  ((f*l) + (j*l))


#####
#total effect of mean t on bird via all pathways
TE_t.mean:= m + (a*k) + (f*l)

#total effect of precip via all pathways
TE_precip:= q + (e*k) + (j*l)

#total effect of climate via all pathways
TE_climate:=  (m + (a*k) + (f*l)) + (q + (e*k) + (j*l))


#Partial effects (i.e. path coves) for individual regressions within SEM (for manually creating path diagrams containing parameters constrained equal between both groups)
PE_t.mean_on_pc1.both:=a
PE_precip_on_pc1.both:=e

PE_t.mean_on_pc2.both:=f
PE_precip_on_pc2.both:=j

PE_pc1.both_on_bird_N:=k
PE_pc2.both_on_bird_N:=l



###(optional) explicity specify any hypothesized (residual) covariances/specify zero covariance.  
#t.mean ~~ precip 


'

 

kma...@aol.com

unread,
Dec 3, 2016, 11:21:27 PM12/3/16
to lavaan
Tim,
Funny you should ask.  I spent the better part of today debugging a similar issue while trying to use effects coding for measurement invariance.

It appears to me that the use of parameter labels overrides the group.equal parameter.  If you need to use parameter labels, I believe that you will need to set the equality constraints across groups in the model syntax rather than with the group.equal parameter.  I believe that this occurs because of the way that the lavaanify() function implements the group.equal parameter.  However, I have not fully parsed how that function works.

Here is an illustration:

# Successful equality constraint using group.equal
model1 <- '
  x1 ~ x2
'
fit1 <- lavaan(
  model = model1,
  data = HolzingerSwineford1939,
  auto.var = TRUE,
  group = "school",
  group.equal = c("regressions"),
  meanstructure = FALSE)
lavInspect(fit1, 'est')[[1]]$beta
lavInspect(fit1, 'est')[[2]]$beta

# Unsuccessful equality constraint using group.equal (with labels)
model2 <- '
  x1 ~ c(a,b)*x2
'
fit2 <- lavaan(
  model = model2,
  data = HolzingerSwineford1939,
  auto.var = TRUE,
  group = "school",
  group.equal = c("regressions"),
  meanstructure = FALSE)
lavInspect(fit2, 'est')[[1]]$beta
lavInspect(fit2, 'est')[[2]]$beta


# Successful equality constraint using labels but not group.equal
model3 <- '
  x1 ~ c(a,b)*x2
  a == b
'
fit3 <- lavaan(
  model = model3,
  data = HolzingerSwineford1939,
  auto.var = TRUE,
  group = "school",
  meanstructure = FALSE)
lavInspect(fit3, 'est')[[1]]$beta
lavInspect(fit3, 'est')[[2]]$beta

lavaanify(model1, ngroups=2, group.equal=c("regressions"))
lavaanify(model2, ngroups=2, group.equal=c("regressions"))
lavaanify(model3, ngroups=2)

Keith
------------------------
Keith A. Markus
John Jay College of Criminal Justice, CUNY
http://jjcweb.jjay.cuny.edu/kmarkus
Frontiers of Test Validity Theory: Measurement, Causation and Meaning.
http://www.routledge.com/books/details/9781841692203/
 

kma...@aol.com

unread,
Dec 3, 2016, 11:47:55 PM12/3/16
to lavaan
PS:  I meant to add that this behavior could actually be quite useful.  If you had a large number of constraints and wanted to release just a few, you could use group.equal and then release a few of them by adding labels.  That assumes that you do not need the labels for the group constrained parameters for some other purpose.

Terrence Jorgensen

unread,
Dec 5, 2016, 5:32:38 AM12/5/16
to lavaan
I know that if you only specify a single parameter label for a regression (ex: y~a*x) then you are by default constraining the regression coefficient (a) to equality between both groups in the multi-group model.

No, if you only specify one label, it will only apply to the first group (check your summary() output to verify).

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

Tim Duclos

unread,
Dec 5, 2016, 2:07:06 PM12/5/16
to lavaan
Yep, you are right Terrence.  I was able to troubleshoot the fact that even if you use a single parameter label across two or more groups, as long as you omit the group.equal argument, then the parameters are still freely estimated for each group respectively. Its only when you specify a group.equal argument that constraints are added (relative to what you specify you want constrained in the group.equal argument). 
Reply all
Reply to author
Forward
0 new messages