Search code examples
rr-lavaan

SEM - Analysis of invariance to test regressions


Let's suppose we have a confirmatory factor analysis CFA with three latent variables (visual, textual, and speed) and that we want to add a regression where speed is the outcome and visual and textual are the explanatory variables (that is to say, expand the CFA to a Structural Equation Model SEM).

Also, let's assume that we have the grouping variable school (2 categories). I want to know if the effects (regression paths) of textual and visual are the same for the two groups or if it is better to have different coefficients for every group.

How can I achieve this?

My main idea is to follow an analysis of invariance calculating a Weak model, a Scalar model, a Strict model, and finally a model where regression coefficients aer also constrained to be equal across groups. Then, if the rmsea and CFI for the last model show not major changes I can say that the coefficients can be assumed to be the same; on the contrary, if rmsea and CFI shows that quality of the model gets worse, it is better to use different estimates for every group.

An alternative would be to make sure the CFA has strict invariance and then add the regression. I could compare the non gruped SEM with the grouped SEM and make a decistion based on the quality of the two models.

library(lavaan)

HS.model <- '  visual =~ x1 + x2 + x3
               textual =~ x4 + x5 + x6
               speed   =~ x7 + x8 + x9 
               speed ~ textual + visual'

fit <- sem(HS.model, 
           data = HolzingerSwineford1939, 
           group = "school")
summary(fit , standardized = TRUE, rsquare = TRUE, fit.measures = TRUE)

fit.Weak <- sem(model = HS.model, data = HolzingerSwineford1939, 
                group = "school", 
                group.equal = c("loadings"))
summary(fit.Weak  , standardized = TRUE, rsquare = TRUE, fit.measures = TRUE)

fit.Scalar <- sem(model = HS.model, data = HolzingerSwineford1939, 
                group = "school", 
                group.equal = c("loadings", "intercepts")
summary(fit.Scalar  , standardized = TRUE, rsquare = TRUE, fit.measures = TRUE)
       
fit.Strict <- sem(model = HS.model, data = HolzingerSwineford1939, 
                   group = "school", 
                   group.equal = c("loadings", "intercepts")
       
fit.Regressors <- sem(model = HS.model, data = HolzingerSwineford1939, 
                       group = "school", 
                       group.equal = c("loadings", "intercepts", "residuals", "regressions")
summary(fit.Regressors  , standardized = TRUE, rsquare = TRUE, fit.measures = TRUE)

Solution

  • Are you looking for an anova?

    > anova(fit, fit.Weak, fit.Strict, fit.Regressors)
    Chi-Squared Difference Test
    
                   Df    AIC    BIC  Chisq Chisq diff Df diff Pr(>Chisq)    
    fit            48 7484.4 7706.8 115.85                                  
    fit.Weak       54 7480.6 7680.8 124.04      8.192       6    0.22436    
    fit.Strict     60 7508.6 7686.6 164.10     40.059       6  4.435e-07 ***
    fit.Regressors 71 7508.5 7645.7 186.00     21.898      11    0.02517 *  
    ---
    Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1