Dear All,
I would like to test group invariance for an individual factor with 4 manifest indicator variables. The manifest indicator variables are ordered and they all have 3 thresholds.
The code for this factor looks the following:
cfa1 <- "F =~ m1 + m2 + m3+ m4"
cfa_fit <- cfa(cfa1, estimator = "WLSMV", data = data)
My strategy of testing group invariance is the following (the group is “sex”):
configural model : no parameter constrains across group
weak model: loadings are fixed to equal across groups
strong model: loadings and thresholds are fixed across groups
The first and second test worked fine, I calculated them with the following code:
config_sex <- cfa(cfa1, data=data, group="sex", parameterization = "theta")
weak_sex <- cfa(cfa1, data=data, group="sex", group.equal=c("loadings"), parameterization = "theta")
config_partet 2 0.6354
weak_partet 5 2.2179 2.2264 3 0.5268
But there seems to be a non-invariance for the third test:
strong_sex <- cfa(cfa1, data=data, group="sex", group.equal=c("loadings","thresholds"), parameterization = "theta")
Df AIC BIC Chisq Chisq diff Df diff Pr(>Chisq)
weak_partet 5 2.2179
strong_partet 11 13.1645 18.468 6 0.005163 **
To examine which item(s) is causing the problem I wanted to replicate the fixed thresholds in a second cfa model and start to free thresholds of single items. Therefore, I defined the following model which should fix at the beginning all item thresholds to be the same across groups and so be equal to the command group.equal=c("thresholds"):
cfa2 <- "F =~ m1 + m2 + m3+ m4
m1 | a*t1 + b*t2 + c*t3
m2 | d *t1 + e*t2 + f*t3
m3 | g*t1 + h*t2 + i*t3
m4 | j*t1 + k*t2 + n*t3"
strong_partial_sex <- cfa(cfa2, data=data, group="sex", group.equal=c("loadings"), parameterization = "theta")
But when I compare the summaries of strong_sex and strong_partial_sex they are not the same (the thresholds seem to be fixed across groups for both models but the estimates are not the same).
Do you know why these two models are not the same?
m1 | c(a, a)*t1 + c(b, b)*t2 + c(c, c)*t3
Dear Terence,
thank you very much for your recommendation.
I tested now again the two models, but their degrees of freedom, estimates and fits are still not the same.
These are the two models I tested:
cfa1 <- "F =~ m1 + m2 + m3+ m4"
strong_sex1 <- cfa(cfa1, data=data, group="sex", group.equal=c("loadings","thresholds"), parameterization = "theta")
cfa2< - "F =~ m1 + m2 + m3+ m4
m1 | c(th1,th1)*t1
m1 | c(th2,th2)*t2
m1 | c(th3,th3)*t3
m2 | c(th4,th4)*t1
m2 | c(th5,th5)*t2
m2 | c(th6,th6)*t3
m3 | c(th7,th7)*t1
m3 | c(th8,th8)*t2
m3 | c(th9,th9)*t3
m4 | c(th10,th10)*t1
m4 | c(th11,th11)*t2
m4 | c(th12,th12)*t3"
strong_sex2 <- cfa(cfa2, data=data, group="sex", group.equal=c("loadings"), parameterization = "theta")
To my understanding, the degrees of freedom, the estimates and fit indices of these two models should be the same.
So my question: what exactly is the command group.equal(“thresholds”) doing?
(I would like free thresholds of item pairs to see which items are problematic in terms of group invariance. Since it is not possible to free thresholds via the group.partial command, I came up with this above second model, where I would then start to free thresholds. But, if this second model is not the same as the first one, I run into a problem…)
Thanks again for your help, I hope you have a bit more insight into this problematic.
Best regards, jsabel
To my understanding, the degrees of freedom, the estimates and fit indices of these two models should be the same.
So my question: what exactly is the command group.equal(“thresholds”) doing?
Since it is not possible to free thresholds via the group.partial command
group.partial = c("m1 | t1", "m1 | t2", "m1 | t3")
Thank you so much for your detailed response, very interesting. I will definitely check out these lavInspect() and parTable() functions!
And its great to know that the group.parial= argument accepts the thresholds. I knew I`ve tried it once and it didnt work, but I guess it was my mistake :)
Thanks again and best regards
jsabel
Am I correct in the assumption that the command for freeing residual variances (which were fixed for testing strict invariance) would be for example for the variable m1:group.partial = c("m1 ~~ m1") ?