Structural Equation Modeling | Exercises 1

1 What we are going to do

  1. Ex.1 – Local Model Fit
  2. Ex.2 – Calculate the model-implied covariance matrix
  3. Ex.3 – 1-factor- vs 2-factor-model
  4. Ex.4 – Fit a second-order CFA
  5. Ex.5 – Compare second-order with first-order CFA

2 Dataset

The data set used throughout is still the European Social Survey ESS4-2008 Edition 4.5. We will restrict the analysis to the Belgian case.

Codebook:

  • gvslvol Standard of living for the old, governments’ responsibility (0 Not governments’ responsibility at all - 10 Entirely governments’ responsibility)

  • gvslvue Standard of living for the unemployed, governments’ responsibility (0 Not governments’ responsibility at all - 10 Entirely governments’ responsibility)

  • gvhlthc Health care for the sick, governments’ responsibility (0 Not governments’ responsibility at all - 10 Entirely governments’ responsibility)

  • gvcldcr Child care services for working parents, governments’ responsibility (0 Not governments’ responsibility at all - 10 Entirely governments’ responsibility)

  • gvjbevn Job for everyone, governments’ responsibility (0 Not governments’ responsibility at all - 10 Entirely governments’ responsibility)

  • gvpdlwk Paid leave from work to care for sick family, governments’ responsibility (0 Not governments’ responsibility at all - 10 Entirely governments’ responsibility)

  • sbstrec Social benefits/services place too great strain on economy (1 Agree strongly - 5 Disagree strongly)

  • sbbsntx Social benefits/services cost businesses too much in taxes/charges (1 Agree strongly - 5 Disagree strongly)

  • sbprvpv Social benefits/services prevent widespread poverty (1 Agree strongly - 5 Disagree strongly)

  • sbeqsoc Social benefits/services lead to a more equal society (1 Agree strongly - 5 Disagree strongly)

  • sbcwkfm Social benefits/services make it easier to combine work and family (1 Agree strongly - 5 Disagree strongly)

  • sblazy Social benefits/services make people lazy (1 Agree strongly - 5 Disagree strongly)

  • sblwcoa Social benefits/services make people less willing care for one another (1 Agree strongly - 5 Disagree strongly)

  • sblwlka Social benefits/services make people less willing look after themselves/family (1 Agree strongly - 5 Disagree strongly)

3 Environment preparation

First, let’s load the necessary packages to load, manipulate, visualize and analyse the data.

# Uncomment this once if you need to install the packages on your system 

### DATA MANIPULATION ###
# install.packages("haven")                 # data import from spss
# install.packages("dplyr")                 # data manipulation
# install.packages("psych")                 # descriptives
# install.packages("stringr")               # string manipulation

### MODELING ###
# install.packages("lavaan")                # SEM modelling
# install.packages("lavaan.survey")         # Wrapper around packages lavaan and survey

### VISUALIZATION ###
# install.packages("tidySEM")               # plotting SEM models
# install.packages("corrplot")              # correlation plots


# Load the packages 

### DATA MANIPULATION ###
library("haven")        
library("dplyr")      
library("psych")
library('stringr')

### MODELING ###
library("lavaan")       

### VISUALIZATION ###
library("tidySEM")
library("corrplot")     

4 Ex.1 – Local Model Fit

  1. Fit the welfare support model with 6 items
  2. Modify the model by allowing error correlations and refit the model
  3. Review the parameter estimates and compare to the first model
  4. Review the fit statistics (global and local)
  5. Verify that the new model indeed fits the data better (perform a chi-squared difference test)
  6. Consider modifying the model even further based on the MIs, revise the model further. Describe its implications (OPTIONAL)
ess_df <- haven::read_sav("https://github.com/albertostefanelli/SEM_labs/raw/master/data/ESS4_belgium.sav")

model_ws_6_1 <-'welf_supp =~ gvslvol + gvslvue + gvhlthc + gvcldcr + gvjbevn + gvpdlwk'


fit_ws_6_1 <- cfa(model_ws_6_1,   # model formula
                 data = ess_df    # data frame
  )

model_ws_6_2 <-'
welf_supp =~ gvslvol + gvslvue + gvhlthc + gvcldcr + gvjbevn + gvpdlwk
gvslvol~~gvhlthc
gvcldcr~~gvpdlwk
'

fit_ws_6_2 <- cfa(model_ws_6_2,   # model formula
                  data = ess_df   # data frame
  )


fitm_model_ws_6_1 <-  fitMeasures(fit_ws_6_1, c("logl",
                                                  "AIC", 
                                                  "BIC", 
                                                  "chisq",
                                                  "df",
                                                  "pvalue",
                                                  "cfi",
                                                  "tli",
                                                  "rmsea"), output = "matrix")

fitm_model_ws_6_2 <- fitMeasures(fit_ws_6_2, c("logl",
                                                  "AIC", 
                                                  "BIC", 
                                                  "chisq",
                                                  "df",
                                                  "pvalue",
                                                  "cfi",
                                                  "tli",
                                                  "rmsea"), output = "matrix")


data.frame(Fit=rownames(fitm_model_ws_6_1),
           "model_ws_6_1" = round(fitm_model_ws_6_1[,1],2),
           "model_ws_6_2" = round(fitm_model_ws_6_2[,1],2)

  
)
          Fit model_ws_6_1 model_ws_6_2
logl     logl    -19550.57    -19406.62
aic       aic     39125.14     38841.24
bic       bic     39190.68     38917.71
chisq   chisq       326.96        39.06
df         df         9.00         7.00
pvalue pvalue         0.00         0.00
cfi       cfi         0.88         0.99
tli       tli         0.80         0.97
rmsea   rmsea         0.14         0.05
anova(fit_ws_6_1,fit_ws_6_2)
Chi-Squared Difference Test

           Df   AIC   BIC   Chisq Chisq diff Df diff            Pr(>Chisq)    
fit_ws_6_2  7 38841 38918  39.063                                             
fit_ws_6_1  9 39125 39191 326.956     287.89       2 < 0.00000000000000022 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

5 Ex.2 – Calculate the model-implied covariance matrix

  1. For the previous models, request the model-implied covariance of the matrix using lavaan’s inspect function.
  2. Calculate the model-implied covariance matrix using the formula:
  3. Compare the two matrices
  4. Calculate the differences between the two matrices (OPTIONAL)
# model-implied var-covariance matrix for observed variables
inspect(fit_ws_6_1, "cov.ov") 
        gvslvl gvslvu gvhlth gvcldc gvjbvn gvpdlw
gvslvol 2.197                                    
gvslvue 0.926  3.675                             
gvhlthc 1.204  0.875  2.169                      
gvcldcr 1.140  0.829  1.077  3.107               
gvjbevn 1.328  0.966  1.255  1.188  5.139        
gvpdlwk 1.163  0.846  1.099  1.041  1.212  3.095 
# same thing, but calculated from model parameters
inspect(fit_ws_6_1, "est")$lambda %*% inspect(fit_ws_6_1, "est")$psi %*% t(inspect(fit_ws_6_1, "est")$lambda) + inspect(fit_ws_6_1, "est")$theta
        gvslvl gvslvu gvhlth gvcldc gvjbvn gvpdlw
gvslvol 2.197                                    
gvslvue 0.926  3.675                             
gvhlthc 1.204  0.875  2.169                      
gvcldcr 1.140  0.829  1.077  3.107               
gvjbevn 1.328  0.966  1.255  1.188  5.139        
gvpdlwk 1.163  0.846  1.099  1.041  1.212  3.095 
# differences between the two matrices 
inspect(fit_ws_6_2, "cov.ov") - inspect(fit_ws_6_1, "cov.ov")
        gvslvl gvslvu gvhlth gvcldc gvjbvn gvpdlw
gvslvol  0.000                                   
gvslvue -0.008  0.000                            
gvhlthc  0.149 -0.010  0.000                     
gvcldcr -0.178  0.045 -0.171  0.000              
gvjbevn -0.018  0.224 -0.021  0.058  0.000       
gvpdlwk -0.186  0.042 -0.178  0.648  0.054  0.000

6 Ex.3 – 1-factor- vs 3-factor-model

  1. Using the welfare criticism items, fit a 1-factor model.
  2. Using the welfare criticism items, fit a 3-factor model.
  3. Verify whether a 1-factor CFA model is appropriate.
    • Review the model parameters.
    • Compare the model fit statistics using a tabular form.
  4. Modify the 3-factor model by dropping items and/or allowing error correlations and compare it with the original model (OPTIONAL)
model_wc_1_factor <-'
wc_crit =~ sbstrec + sbbsntx + sbprvpv + sbeqsoc + sbcwkfm + sblazy + sblwcoa + sblwlka
'

fit_wc_1_factor <- cfa(model_wc_1_factor, # model formula
                      data = ess_df       # data frame
  )

summary(fit_wc_1_factor, standardized=TRUE)
lavaan 0.6-10 ended normally after 31 iterations

  Estimator                                         ML
  Optimization method                           NLMINB
  Number of model parameters                        16
                                                      
                                                  Used       Total
  Number of observations                          1679        1760
                                                                  
Model Test User Model:
                                                      
  Test statistic                               756.304
  Degrees of freedom                                20
  P-value (Chi-square)                           0.000

Parameter Estimates:

  Standard errors                             Standard
  Information                                 Expected
  Information saturated (h1) model          Structured

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  wc_crit =~                                                            
    sbstrec           1.000                               0.373    0.366
    sbbsntx           0.991    0.099   10.054    0.000    0.370    0.370
    sbprvpv          -0.002    0.065   -0.026    0.979   -0.001   -0.001
    sbeqsoc          -0.249    0.064   -3.898    0.000   -0.093   -0.111
    sbcwkfm          -0.055    0.057   -0.958    0.338   -0.021   -0.026
    sblazy            2.021    0.156   12.983    0.000    0.754    0.715
    sblwcoa           2.085    0.159   13.085    0.000    0.778    0.753
    sblwlka           1.944    0.150   12.928    0.000    0.726    0.700

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .sbstrec           0.902    0.033   27.733    0.000    0.902    0.866
   .sbbsntx           0.861    0.031   27.697    0.000    0.861    0.863
   .sbprvpv           0.767    0.026   28.974    0.000    0.767    1.000
   .sbeqsoc           0.690    0.024   28.875    0.000    0.690    0.988
   .sbcwkfm           0.602    0.021   28.969    0.000    0.602    0.999
   .sblazy            0.543    0.027   19.999    0.000    0.543    0.489
   .sblwcoa           0.463    0.026   17.815    0.000    0.463    0.434
   .sblwlka           0.548    0.026   20.773    0.000    0.548    0.510
    wc_crit           0.139    0.020    6.869    0.000    1.000    1.000
model_wc_3_factor <-'
## Economic criticism ##
wc_econo =~ sbstrec + sbbsntx
## Social criticism ## 
wc_socia =~ sbprvpv + sbeqsoc + sbcwkfm
##  Moral criticism ##
wc_moral =~ sblazy + sblwcoa + sblwlka
'

fit_wc_3_factor <- cfa(model_wc_3_factor,  # model formula
                      data = ess_df        # data frame
  )

summary(fit_wc_3_factor, standardized=TRUE)
lavaan 0.6-10 ended normally after 36 iterations

  Estimator                                         ML
  Optimization method                           NLMINB
  Number of model parameters                        19
                                                      
                                                  Used       Total
  Number of observations                          1679        1760
                                                                  
Model Test User Model:
                                                      
  Test statistic                                71.348
  Degrees of freedom                                17
  P-value (Chi-square)                           0.000

Parameter Estimates:

  Standard errors                             Standard
  Information                                 Expected
  Information saturated (h1) model          Structured

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  wc_econo =~                                                           
    sbstrec           1.000                               0.628    0.616
    sbbsntx           1.001    0.093   10.817    0.000    0.629    0.629
  wc_socia =~                                                           
    sbprvpv           1.000                               0.462    0.527
    sbeqsoc           1.493    0.166    9.011    0.000    0.689    0.824
    sbcwkfm           0.631    0.055   11.461    0.000    0.291    0.375
  wc_moral =~                                                           
    sblazy            1.000                               0.749    0.710
    sblwcoa           1.058    0.045   23.285    0.000    0.792    0.766
    sblwlka           0.977    0.043   22.843    0.000    0.732    0.706

Covariances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  wc_econo ~~                                                           
    wc_socia         -0.024    0.011   -2.093    0.036   -0.082   -0.082
    wc_moral          0.250    0.023   10.872    0.000    0.532    0.532
  wc_socia ~~                                                           
    wc_moral         -0.034    0.012   -2.915    0.004   -0.099   -0.099

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .sbstrec           0.647    0.042   15.381    0.000    0.647    0.621
   .sbbsntx           0.603    0.041   14.584    0.000    0.603    0.604
   .sbprvpv           0.554    0.030   18.722    0.000    0.554    0.722
   .sbeqsoc           0.224    0.051    4.404    0.000    0.224    0.320
   .sbcwkfm           0.518    0.020   25.832    0.000    0.518    0.859
   .sblazy            0.551    0.027   20.083    0.000    0.551    0.495
   .sblwcoa           0.441    0.027   16.639    0.000    0.441    0.413
   .sblwlka           0.539    0.027   20.320    0.000    0.539    0.502
    wc_econo          0.395    0.045    8.689    0.000    1.000    1.000
    wc_socia          0.213    0.029    7.328    0.000    1.000    1.000
    wc_moral          0.561    0.039   14.477    0.000    1.000    1.000
fitm_model_wc_1_factor <-  fitMeasures(fit_wc_1_factor, c("logl",
                                                  "AIC", 
                                                  "BIC", 
                                                  "chisq",
                                                  "df",
                                                  "pvalue",
                                                  "cfi",
                                                  "tli",
                                                  "rmsea"), output = "matrix")

fitm_model_wc_3_factor <- fitMeasures(fit_wc_3_factor, c("logl",
                                                  "AIC", 
                                                  "BIC", 
                                                  "chisq",
                                                  "df",
                                                  "pvalue",
                                                  "cfi",
                                                  "tli",
                                                  "rmsea"), output = "matrix")






data.frame("Fit Indices" = rownames(fitm_model_wc_1_factor),
           "model_wc_1_factor" = round(fitm_model_wc_1_factor[, 1], 2),
           "model_wc_3_factor" = round(fitm_model_wc_3_factor[, 1], 2)

  
)
       Fit.Indices model_wc_1_factor model_wc_3_factor
logl          logl         -17512.44         -17169.96
aic            aic          35056.88          34377.93
bic            bic          35143.70          34481.02
chisq        chisq            756.30             71.35
df              df             20.00             17.00
pvalue      pvalue              0.00              0.00
cfi            cfi              0.69              0.98
tli            tli              0.57              0.96
rmsea        rmsea              0.15              0.04
## OPTIONAL ##

model_wc_3_factor_mod <-'
## Economic criticism ##
wc_econo =~ sbstrec + sbbsntx
## Social criticism ## 
wc_socia =~ sbprvpv + sbeqsoc + sbcwkfm
##  Moral criticism ##
wc_moral =~ sblazy + sblwcoa + sblwlka
sblwcoa ~~ sblwlka
'

fit_wc_3_factor_mod <- cfa(model_wc_3_factor_mod, # model formula
                           data = ess_df         # data frame
  )

summary(fit_wc_3_factor_mod, standardized=TRUE)
lavaan 0.6-10 ended normally after 37 iterations

  Estimator                                         ML
  Optimization method                           NLMINB
  Number of model parameters                        20
                                                      
                                                  Used       Total
  Number of observations                          1679        1760
                                                                  
Model Test User Model:
                                                      
  Test statistic                                56.695
  Degrees of freedom                                16
  P-value (Chi-square)                           0.000

Parameter Estimates:

  Standard errors                             Standard
  Information                                 Expected
  Information saturated (h1) model          Structured

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  wc_econo =~                                                           
    sbstrec           1.000                               0.627    0.614
    sbbsntx           1.005    0.091   11.041    0.000    0.630    0.631
  wc_socia =~                                                           
    sbprvpv           1.000                               0.460    0.525
    sbeqsoc           1.501    0.166    9.038    0.000    0.691    0.827
    sbcwkfm           0.632    0.055   11.465    0.000    0.291    0.375
  wc_moral =~                                                           
    sblazy            1.000                               0.834    0.791
    sblwcoa           0.846    0.060   14.099    0.000    0.706    0.683
    sblwlka           0.773    0.057   13.570    0.000    0.645    0.622

Covariances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
 .sblwcoa ~~                                                            
   .sblwlka           0.138    0.033    4.157    0.000    0.138    0.225
  wc_econo ~~                                                           
    wc_socia         -0.024    0.011   -2.119    0.034   -0.083   -0.083
    wc_moral          0.290    0.026   10.951    0.000    0.555    0.555
  wc_socia ~~                                                           
    wc_moral         -0.045    0.013   -3.316    0.001   -0.116   -0.116

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .sbstrec           0.649    0.041   15.699    0.000    0.649    0.623
   .sbbsntx           0.601    0.041   14.740    0.000    0.601    0.602
   .sbprvpv           0.555    0.029   18.851    0.000    0.555    0.724
   .sbeqsoc           0.221    0.051    4.348    0.000    0.221    0.317
   .sbcwkfm           0.518    0.020   25.860    0.000    0.518    0.860
   .sblazy            0.417    0.047    8.834    0.000    0.417    0.375
   .sblwcoa           0.571    0.039   14.605    0.000    0.571    0.534
   .sblwlka           0.659    0.037   17.567    0.000    0.659    0.613
    wc_econo          0.393    0.045    8.795    0.000    1.000    1.000
    wc_socia          0.212    0.029    7.333    0.000    1.000    1.000
    wc_moral          0.695    0.057   12.132    0.000    1.000    1.000
fitm_model_wc_3_factor_mod <- fitMeasures(fit_wc_3_factor_mod, c("logl",
                                                  "AIC", 
                                                  "BIC", 
                                                  "chisq",
                                                  "df",
                                                  "pvalue",
                                                  "cfi",
                                                  "tli",
                                                  "rmsea"), output = "matrix")


data.frame("Fit Indices" = rownames(fitm_model_wc_1_factor),
           "model_wc_3_factor" = round(fitm_model_wc_3_factor[, 1], 2),
           "model_wc_3_factor_mod" = round(fitm_model_wc_3_factor_mod[, 1], 2)
  
)
       Fit.Indices model_wc_3_factor model_wc_3_factor_mod
logl          logl         -17169.96             -17162.64
aic            aic          34377.93              34365.27
bic            bic          34481.02              34473.79
chisq        chisq             71.35                 56.70
df              df             17.00                 16.00
pvalue      pvalue              0.00                  0.00
cfi            cfi              0.98                  0.98
tli            tli              0.96                  0.97
rmsea        rmsea              0.04                  0.04

7 Ex.4 – Second order model

  1. Fit a second-order model with the three dimensions of welfare criticism.
  2. Review the model output using the summary function. Does the model fit well?
  3. Review the \(R^2\) values of the first-order latent variables. Which first-order factor is explained best by the second-order factor?
  4. Request model modification indices and explore model modifications.
  5. Remove low loadings and see if the model improves (OPTIONAL)
model_wc_2_order <-'
## Economic criticism ##
wc_econo =~ sbstrec + sbbsntx
## Social criticism ## 
wc_socia =~ sbprvpv + sbeqsoc + sbcwkfm
##  Moral criticism ##
wc_moral =~ sblazy + sblwcoa + sblwlka
## Second Order Welfare Criticism ## 
wc_crit =~ wc_econo + wc_socia + wc_moral
'

fit_wc_2_order <- cfa(model_wc_2_order,  # model formula
                      data = ess_df      # data frame
  )

summary(fit_wc_2_order, standardized=TRUE)
lavaan 0.6-10 ended normally after 54 iterations

  Estimator                                         ML
  Optimization method                           NLMINB
  Number of model parameters                        19
                                                      
                                                  Used       Total
  Number of observations                          1679        1760
                                                                  
Model Test User Model:
                                                      
  Test statistic                                71.348
  Degrees of freedom                                17
  P-value (Chi-square)                           0.000

Parameter Estimates:

  Standard errors                             Standard
  Information                                 Expected
  Information saturated (h1) model          Structured

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  wc_econo =~                                                           
    sbstrec           1.000                               0.628    0.616
    sbbsntx           1.001    0.093   10.817    0.000    0.629    0.629
  wc_socia =~                                                           
    sbprvpv           1.000                               0.462    0.527
    sbeqsoc           1.493    0.166    9.011    0.000    0.689    0.824
    sbcwkfm           0.631    0.055   11.461    0.000    0.291    0.375
  wc_moral =~                                                           
    sblazy            1.000                               0.749    0.710
    sblwcoa           1.058    0.045   23.285    0.000    0.792    0.766
    sblwlka           0.977    0.043   22.843    0.000    0.732    0.706
  wc_crit =~                                                            
    wc_econo          1.000                               0.665    0.665
    wc_socia         -0.136    0.047   -2.873    0.004   -0.124   -0.124
    wc_moral          1.434    0.675    2.126    0.033    0.800    0.800

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .sbstrec           0.647    0.042   15.381    0.000    0.647    0.621
   .sbbsntx           0.603    0.041   14.584    0.000    0.603    0.604
   .sbprvpv           0.554    0.030   18.722    0.000    0.554    0.722
   .sbeqsoc           0.224    0.051    4.404    0.000    0.224    0.320
   .sbcwkfm           0.518    0.020   25.832    0.000    0.518    0.859
   .sblazy            0.551    0.027   20.083    0.000    0.551    0.495
   .sblwcoa           0.441    0.027   16.639    0.000    0.441    0.413
   .sblwlka           0.539    0.027   20.320    0.000    0.539    0.502
   .wc_econo          0.220    0.087    2.546    0.011    0.558    0.558
   .wc_socia          0.210    0.029    7.349    0.000    0.985    0.985
   .wc_moral          0.202    0.168    1.201    0.230    0.360    0.360
    wc_crit           0.175    0.085    2.062    0.039    1.000    1.000
inspect(fit_wc_2_order, "r2")
 sbstrec  sbbsntx  sbprvpv  sbeqsoc  sbcwkfm   sblazy  sblwcoa  sblwlka wc_econo wc_socia wc_moral 
   0.379    0.396    0.278    0.680    0.141    0.505    0.587    0.498    0.442    0.015    0.640 
mi<-inspect(fit_wc_2_order, "mi") 
# sort from high to low mi.sorted[1:5,] 
mi.sorted<-mi[order(-mi$mi), ] 
# # only display some large MI values
head(mi.sorted, 5)
        lhs op     rhs     mi    epc sepc.lv sepc.all sepc.nox
25 wc_econo =~ sbeqsoc 37.330 -0.327  -0.205   -0.246   -0.246
24 wc_econo =~ sbprvpv 26.502  0.211   0.132    0.151    0.151
49  sbstrec ~~ sbprvpv 19.613  0.079   0.079    0.132    0.132
43  wc_crit =~ sbeqsoc 19.285 -0.371  -0.155   -0.186   -0.186
62  sbprvpv ~~ sbcwkfm 19.285  0.241   0.241    0.450    0.450

Maybe does not makes sense to impose other modifications for this model.

## OPTIONAL ##

model_wc_2_order_mod <-'
## Economic criticism ##
wc_econo =~ sbstrec + sbbsntx
## Social criticism ## 
wc_socia =~ sbprvpv + sbeqsoc
##  Moral criticism ##
wc_moral =~ sblazy + sblwcoa + sblwlka
## Second Order Welfare Criticism ## 
wc_crit =~ wc_econo + wc_socia + wc_moral
'

fit_wc_2_order_mod <- cfa(model_wc_2_order_mod,  # model formula
                          data = ess_df          # data frame
  ) 

summary(fit_wc_2_order_mod, standardized=TRUE)
lavaan 0.6-10 did NOT end normally after 697 iterations
** WARNING ** Estimates below are most likely unreliable

  Estimator                                         ML
  Optimization method                           NLMINB
  Number of model parameters                        17
                                                      
                                                  Used       Total
  Number of observations                          1687        1760
                                                                  
Model Test User Model:
                                                      
  Test statistic                                    NA
  Degrees of freedom                                NA

Parameter Estimates:

  Standard errors                             Standard
  Information                                 Expected
  Information saturated (h1) model          Structured

Latent Variables:
                   Estimate   Std.Err  z-value  P(>|z|)   Std.lv   Std.all 
  wc_econo =~                                                              
    sbstrec            1.000                                0.650     0.637
    sbbsntx            0.939       NA                       0.611     0.611
  wc_socia =~                                                              
    sbprvpv            1.000                               47.670    54.288
    sbeqsoc            0.000       NA                       0.007     0.008
  wc_moral =~                                                              
    sblazy             1.000                                0.746     0.708
    sblwcoa            1.062       NA                       0.792     0.766
    sblwlka            0.981       NA                       0.732     0.707
  wc_crit =~                                                               
    wc_econo           1.000                                1.282     1.282
    wc_socia           0.116       NA                       0.002     0.002
    wc_moral           0.373       NA                       0.416     0.416

Variances:
                   Estimate   Std.Err  z-value  P(>|z|)   Std.lv   Std.all 
   .sbstrec            0.619       NA                       0.619     0.594
   .sbbsntx            0.625       NA                       0.625     0.626
   .sbprvpv        -2271.620       NA                   -2271.620 -2946.209
   .sbeqsoc            0.697       NA                       0.697     1.000
   .sblazy             0.554       NA                       0.554     0.499
   .sblwcoa            0.442       NA                       0.442     0.413
   .sblwlka            0.536       NA                       0.536     0.500
   .wc_econo          -0.272       NA                      -0.643    -0.643
   .wc_socia        2272.382       NA                       1.000     1.000
   .wc_moral           0.460       NA                       0.827     0.827
    wc_crit            0.695       NA                       1.000     1.000

The model does not fit. Why is it the case ?

8 Ex.5 – Compare first-order with second-order model

  1. How many degrees of freedom are lost between the two models? Why?
  2. Statistically compare model fit: does the second-order factor model fit significantly worse than the first-order factor model?
  3. Fit a model with social and moral criticism of the welfare state as latent variable. Remove the latent factors correlations. Compare the fit (OPTIONAL).
summary(fit_wc_3_factor)
lavaan 0.6-10 ended normally after 36 iterations

  Estimator                                         ML
  Optimization method                           NLMINB
  Number of model parameters                        19
                                                      
                                                  Used       Total
  Number of observations                          1679        1760
                                                                  
Model Test User Model:
                                                      
  Test statistic                                71.348
  Degrees of freedom                                17
  P-value (Chi-square)                           0.000

Parameter Estimates:

  Standard errors                             Standard
  Information                                 Expected
  Information saturated (h1) model          Structured

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)
  wc_econo =~                                         
    sbstrec           1.000                           
    sbbsntx           1.001    0.093   10.817    0.000
  wc_socia =~                                         
    sbprvpv           1.000                           
    sbeqsoc           1.493    0.166    9.011    0.000
    sbcwkfm           0.631    0.055   11.461    0.000
  wc_moral =~                                         
    sblazy            1.000                           
    sblwcoa           1.058    0.045   23.285    0.000
    sblwlka           0.977    0.043   22.843    0.000

Covariances:
                   Estimate  Std.Err  z-value  P(>|z|)
  wc_econo ~~                                         
    wc_socia         -0.024    0.011   -2.093    0.036
    wc_moral          0.250    0.023   10.872    0.000
  wc_socia ~~                                         
    wc_moral         -0.034    0.012   -2.915    0.004

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)
   .sbstrec           0.647    0.042   15.381    0.000
   .sbbsntx           0.603    0.041   14.584    0.000
   .sbprvpv           0.554    0.030   18.722    0.000
   .sbeqsoc           0.224    0.051    4.404    0.000
   .sbcwkfm           0.518    0.020   25.832    0.000
   .sblazy            0.551    0.027   20.083    0.000
   .sblwcoa           0.441    0.027   16.639    0.000
   .sblwlka           0.539    0.027   20.320    0.000
    wc_econo          0.395    0.045    8.689    0.000
    wc_socia          0.213    0.029    7.328    0.000
    wc_moral          0.561    0.039   14.477    0.000
summary(fit_wc_2_order)
lavaan 0.6-10 ended normally after 54 iterations

  Estimator                                         ML
  Optimization method                           NLMINB
  Number of model parameters                        19
                                                      
                                                  Used       Total
  Number of observations                          1679        1760
                                                                  
Model Test User Model:
                                                      
  Test statistic                                71.348
  Degrees of freedom                                17
  P-value (Chi-square)                           0.000

Parameter Estimates:

  Standard errors                             Standard
  Information                                 Expected
  Information saturated (h1) model          Structured

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)
  wc_econo =~                                         
    sbstrec           1.000                           
    sbbsntx           1.001    0.093   10.817    0.000
  wc_socia =~                                         
    sbprvpv           1.000                           
    sbeqsoc           1.493    0.166    9.011    0.000
    sbcwkfm           0.631    0.055   11.461    0.000
  wc_moral =~                                         
    sblazy            1.000                           
    sblwcoa           1.058    0.045   23.285    0.000
    sblwlka           0.977    0.043   22.843    0.000
  wc_crit =~                                          
    wc_econo          1.000                           
    wc_socia         -0.136    0.047   -2.873    0.004
    wc_moral          1.434    0.675    2.126    0.033

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)
   .sbstrec           0.647    0.042   15.381    0.000
   .sbbsntx           0.603    0.041   14.584    0.000
   .sbprvpv           0.554    0.030   18.722    0.000
   .sbeqsoc           0.224    0.051    4.404    0.000
   .sbcwkfm           0.518    0.020   25.832    0.000
   .sblazy            0.551    0.027   20.083    0.000
   .sblwcoa           0.441    0.027   16.639    0.000
   .sblwlka           0.539    0.027   20.320    0.000
   .wc_econo          0.220    0.087    2.546    0.011
   .wc_socia          0.210    0.029    7.349    0.000
   .wc_moral          0.202    0.168    1.201    0.230
    wc_crit           0.175    0.085    2.062    0.039
anova(fit_wc_3_factor, fit_wc_2_order)
Chi-Squared Difference Test

                Df   AIC   BIC  Chisq      Chisq diff Df diff Pr(>Chisq)
fit_wc_3_factor 17 34378 34481 71.348                                   
fit_wc_2_order  17 34378 34481 71.348 0.0000000010737       0           
## OPTIONAL ##

model_wc_2_factor_corr <-'

## Social criticism ## 
wc_socia =~ sbprvpv + sbeqsoc + sbcwkfm
##  Moral criticism ##
wc_moral =~ sblazy + sblwcoa + sblwlka

## fixing covariance of LV to zero 
wc_socia ~~ 0*wc_moral
'

fit_wc_2_factor_corr <- cfa(model_wc_2_factor_corr,  # model formula
                            data = ess_df            # data frame
  )

summary(fit_wc_2_factor_corr, fit.measures=TRUE, standardized=TRUE)
lavaan 0.6-10 ended normally after 26 iterations

  Estimator                                         ML
  Optimization method                           NLMINB
  Number of model parameters                        12
                                                      
                                                  Used       Total
  Number of observations                          1711        1760
                                                                  
Model Test User Model:
                                                      
  Test statistic                                27.612
  Degrees of freedom                                 9
  P-value (Chi-square)                           0.001

Model Test Baseline Model:

  Test statistic                              1924.056
  Degrees of freedom                                15
  P-value                                        0.000

User Model versus Baseline Model:

  Comparative Fit Index (CFI)                    0.990
  Tucker-Lewis Index (TLI)                       0.984

Loglikelihood and Information Criteria:

  Loglikelihood user model (H0)             -12862.383
  Loglikelihood unrestricted model (H1)             NA
                                                      
  Akaike (AIC)                               25748.765
  Bayesian (BIC)                             25814.103
  Sample-size adjusted Bayesian (BIC)        25775.981

Root Mean Square Error of Approximation:

  RMSEA                                          0.035
  90 Percent confidence interval - lower         0.020
  90 Percent confidence interval - upper         0.050
  P-value RMSEA <= 0.05                          0.951

Standardized Root Mean Square Residual:

  SRMR                                           0.031

Parameter Estimates:

  Standard errors                             Standard
  Information                                 Expected
  Information saturated (h1) model          Structured

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  wc_socia =~                                                           
    sbprvpv           1.000                               0.494    0.565
    sbeqsoc           1.305    0.135    9.645    0.000    0.645    0.770
    sbcwkfm           0.615    0.053   11.514    0.000    0.304    0.392
  wc_moral =~                                                           
    sblazy            1.000                               0.729    0.691
    sblwcoa           1.113    0.050   22.341    0.000    0.812    0.784
    sblwlka           1.006    0.045   22.454    0.000    0.734    0.708

Covariances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  wc_socia ~~                                                           
    wc_moral          0.000                               0.000    0.000

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .sbprvpv           0.521    0.030   17.265    0.000    0.521    0.681
   .sbeqsoc           0.285    0.043    6.691    0.000    0.285    0.407
   .sbcwkfm           0.510    0.020   25.859    0.000    0.510    0.847
   .sblazy            0.582    0.028   20.678    0.000    0.582    0.522
   .sblwcoa           0.412    0.028   14.529    0.000    0.412    0.385
   .sblwlka           0.535    0.027   19.665    0.000    0.535    0.498
    wc_socia          0.244    0.031    7.877    0.000    1.000    1.000
    wc_moral          0.532    0.038   13.970    0.000    1.000    1.000

9 !!Support Ukraine!!