First part of this SEM exercise introduces data simulation for both singe and multi-group analysis. Second, an example of multi-group analysis is given (including measurement invariance testing across groups).

Simulate SEM data based on previous research

We will create a simulation data based on the previous SEM exercise results with simstandard package.

First, let's define the model we are going to use. Details are available in SEM_R.Rmd and SEM_R.html.

We will use the marker variable method (for other scaling options, see Beaujean, 2014, pp. 41) to scale the latent variables: One indicator (manifest) variable's loading for each latent variable is constrained to an arbitrary value (usually 1).

library(lavaan)

sem_model <- '
# Factors
ENC =~ NA*v5 + v7 + 1*v17   # Encouraging leadership
BUI =~ 1*v42r + v43         # Build-up of work requirements
PSY =~ 1*v44 + v45          # Psychic stress of the work
# Regressions
PSY ~ ENC + BUI             # Predict PSY with ENC and BUI
# Covariances
ENC ~~ BUI                  # Let ENC and BUI correlate
'

Second, we need to fit the model:

# read in dfttu4 data (n = 447)
dfttu4 <- read.csv("data1_csv.dat", header = T)

sem_model_fit <- sem(sem_model, 
                    data=dfttu4,
                    mimic="mplus",
                    group = NULL, # no grouping variable (e.g., gender, control/intervention,...)
                    cluster = NULL, # no clustering variable (e.g., multilevel data may contain several values for each participant)
                    missing = "fiml.x" # full information maximum likelihood approach
                    )

Is our model under/just/overidentified?

# how many parameters are to be estimated in the model?
inspect(sem_model_fit) # 24
## $lambda
##      ENC BUI PSY
## v5     1   0   0
## v7     2   0   0
## v17    0   0   0
## v42r   0   0   0
## v43    0   3   0
## v44    0   0   0
## v45    0   0   4
## 
## $theta
##      v5 v7 v17 v42r v43 v44 v45
## v5    8                        
## v7    0  9                     
## v17   0  0  10                 
## v42r  0  0   0   11            
## v43   0  0   0    0  12        
## v44   0  0   0    0   0  13    
## v45   0  0   0    0   0   0  14
## 
## $psi
##     ENC BUI PSY
## ENC  15        
## BUI   7  16    
## PSY   0   0  17
## 
## $beta
##     ENC BUI PSY
## ENC   0   0   0
## BUI   0   0   0
## PSY   5   6   0
## 
## $nu
##      intrcp
## v5       18
## v7       19
## v17      20
## v42r     21
## v43      22
## v44      23
## v45      24
## 
## $alpha
##     intrcp
## ENC      0
## BUI      0
## PSY      0
# the model is overidentified (good!) as there are 28 non-redundant elements [7(7+1)/2 = 56/2 = 28]
# and 24 parameters to be estimated (28 - 24 = 4):
# 
# 4 manifest variable loadings on three factors (lambda matrix)
# 7 error variances of manifest variables (theta matrix)
# 3 latent variances and 1 covariance (psi matrix)
# 2 regressions (beta matrix)
# 7 intercepts(nu matrix)

We may proceed as the model is overidentified.

Third, we'll check the results.

Note that “Estimate” column reports unstandardized values, while “Std.lv” column reports values when latent variables are standardized and “Std.all” column values reflect situation when both latent and observed (manifest) values are standardized.

summary(sem_model_fit, 
        standardized=TRUE, 
        rsq=TRUE, 
        fit.measures = T)
## lavaan 0.6.14 ended normally after 41 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        24
## 
##   Number of observations                           447
##   Number of missing patterns                        10
## 
## Model Test User Model:
##                                                       
##   Test statistic                                62.390
##   Degrees of freedom                                11
##   P-value (Chi-square)                           0.000
## 
## Model Test Baseline Model:
## 
##   Test statistic                              1131.720
##   Degrees of freedom                                21
##   P-value                                        0.000
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    0.954
##   Tucker-Lewis Index (TLI)                       0.912
##                                                       
##   Robust Comparative Fit Index (CFI)             0.954
##   Robust Tucker-Lewis Index (TLI)                0.912
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)              -4334.157
##   Loglikelihood unrestricted model (H1)      -4302.962
##                                                       
##   Akaike (AIC)                                8716.315
##   Bayesian (BIC)                              8814.776
##   Sample-size adjusted Bayesian (SABIC)       8738.610
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.102
##   90 Percent confidence interval - lower         0.078
##   90 Percent confidence interval - upper         0.128
##   P-value H_0: RMSEA <= 0.050                    0.000
##   P-value H_0: RMSEA >= 0.080                    0.938
##                                                       
##   Robust RMSEA                                   0.103
##   90 Percent confidence interval - lower         0.079
##   90 Percent confidence interval - upper         0.128
##   P-value H_0: Robust RMSEA <= 0.050             0.000
##   P-value H_0: Robust RMSEA >= 0.080             0.940
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.062
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Observed
##   Observed information based on                Hessian
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC =~                                                                
##     v5                0.896    0.048   18.766    0.000    0.962    0.814
##     v7                0.765    0.043   17.629    0.000    0.822    0.768
##     v17               1.000                               1.074    0.886
##   BUI =~                                                                
##     v42r              1.000                               0.777    0.672
##     v43               0.798    0.089    8.924    0.000    0.620    0.571
##   PSY =~                                                                
##     v44               1.000                               1.118    0.901
##     v45               0.592    0.068    8.702    0.000    0.662    0.551
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   PSY ~                                                                 
##     ENC              -0.104    0.063   -1.653    0.098   -0.100   -0.100
##     BUI               1.223    0.152    8.028    0.000    0.850    0.850
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC ~~                                                                
##     BUI              -0.253    0.062   -4.092    0.000   -0.303   -0.303
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5                3.818    0.056   68.091    0.000    3.818    3.229
##    .v7                3.436    0.051   67.756    0.000    3.436    3.211
##    .v17               3.280    0.058   56.971    0.000    3.280    2.705
##    .v42r              2.992    0.055   54.600    0.000    2.992    2.584
##    .v43               3.803    0.052   73.253    0.000    3.803    3.501
##    .v44               3.277    0.059   55.754    0.000    3.277    2.639
##    .v45               2.387    0.057   42.027    0.000    2.387    1.990
##     ENC               0.000                               0.000    0.000
##     BUI               0.000                               0.000    0.000
##    .PSY               0.000                               0.000    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5                0.473    0.047    9.978    0.000    0.473    0.338
##    .v7                0.470    0.041   11.380    0.000    0.470    0.410
##    .v17               0.317    0.048    6.588    0.000    0.317    0.216
##    .v42r              0.736    0.080    9.226    0.000    0.736    0.549
##    .v43               0.795    0.067   11.829    0.000    0.795    0.674
##    .v44               0.291    0.119    2.458    0.014    0.291    0.189
##    .v45               1.002    0.079   12.747    0.000    1.002    0.696
##     ENC               1.153    0.105   10.934    0.000    1.000    1.000
##     BUI               0.604    0.098    6.186    0.000    1.000    1.000
##    .PSY               0.269    0.132    2.035    0.042    0.215    0.215
## 
## R-Square:
##                    Estimate
##     v5                0.662
##     v7                0.590
##     v17               0.784
##     v42r              0.451
##     v43               0.326
##     v44               0.811
##     v45               0.304
##     PSY               0.785
# Latent Variables:
#                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
#   ENC =~                                                                
#     v5                0.896    0.048   18.766    0.000    0.962    0.814
#     v7                0.765    0.043   17.629    0.000    0.822    0.768
#     v17               1.000                               1.074    0.886
#   BUI =~                                                                
#     v42r              1.000                               0.777    0.672
#     v43               0.798    0.089    8.924    0.000    0.620    0.571
#   PSY =~                                                                
#     v44               1.000                               1.118    0.901
#     v45               0.592    0.068    8.702    0.000    0.662    0.551
# 
# Regressions:
#                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
#   PSY ~                                                                 
#     ENC              -0.104    0.063   -1.653    0.098   -0.100   -0.100
#     BUI               1.223    0.152    8.028    0.000    0.850    0.850
# 
# Covariances:
#                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
#   ENC ~~                                                                
#     BUI              -0.253    0.062   -4.092    0.000   -0.303   -0.303
# Variances:
#                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
#    .v5                0.473    0.047    9.978    0.000    0.473    0.338
#    .v7                0.470    0.041   11.380    0.000    0.470    0.410
#    .v17               0.317    0.048    6.588    0.000    0.317    0.216
#    .v42r              0.736    0.080    9.226    0.000    0.736    0.549
#    .v43               0.795    0.067   11.829    0.000    0.795    0.674
#    .v44               0.291    0.119    2.458    0.014    0.291    0.189
#    .v45               1.002    0.079   12.747    0.000    1.002    0.696
#     ENC               1.153    0.105   10.934    0.000    1.000    1.000
#     BUI               0.604    0.098    6.186    0.000    1.000    1.000
#    .PSY               0.269    0.132    2.035    0.042    0.215    0.215

There is also a third type of standardization (“Std.nox”) where variables are standardized except for the exogenous observed (manifest) variables:

head(parameterEstimates(sem_model_fit, standardized = T, ci = F))
##   lhs op  rhs   est    se      z pvalue std.lv std.all std.nox
## 1 ENC =~   v5 0.896 0.048 18.766      0  0.962   0.814   0.814
## 2 ENC =~   v7 0.765 0.043 17.629      0  0.822   0.768   0.768
## 3 ENC =~  v17 1.000 0.000     NA     NA  1.074   0.886   0.886
## 4 BUI =~ v42r 1.000 0.000     NA     NA  0.777   0.672   0.672
## 5 BUI =~  v43 0.798 0.089  8.924      0  0.620   0.571   0.571
## 6 PSY =~  v44 1.000 0.000     NA     NA  1.118   0.901   0.901
#   lhs op  rhs   est    se      z pvalue std.lv std.all std.nox
# 1 ENC =~   v5 0.896 0.048 18.766      0  0.962   0.814   0.814
# 2 ENC =~   v7 0.765 0.043 17.629      0  0.822   0.768   0.768
# 3 ENC =~  v17 1.000 0.000     NA     NA  1.074   0.886   0.886
# 4 BUI =~ v42r 1.000 0.000     NA     NA  0.777   0.672   0.672
# 5 BUI =~  v43 0.798 0.089  8.924      0  0.620   0.571   0.571
# 6 PSY =~  v44 1.000 0.000     NA     NA  1.118   0.901   0.901

This is the figure based on standardized results:

library(semPlot)

semPlot::semPaths(sem_model_fit, 
         layout="tree",
         "std", # display standardized parameter estimates
         edge.label.cex=0.7,
         edge.width=0.2,
         edge.color="black",
         optimizeLatRes=TRUE,
         label.scale=TRUE,
         normalize=TRUE,
         fade=FALSE,
         # filetype = "jpg", # save file
         # filename = "SEM_figure",
         as.expression=c("nodes"))

library(lavaan)

# we'll use the same syntax than before, but upgraded with estimates taken from the results of the earlier SEM model (above)
sem_model_simulation <- '

# Factors
ENC =~ 0.81*v5   + 0.77*v7 + 0.87*v17   # standardized loadings from "Std.all" output above
BUI =~ 0.67*v42r + 0.57*v43
PSY =~ 0.90*v44  + 0.55*v45

# Regressions
PSY ~ -0.10*ENC + 0.85*BUI              # standardized path coefficients from "Std.all" output above

# Covariances
ENC ~~ -.30*BUI                         # covariance from "Std.all" output above
'

# install.packages("simstandard")
library(simstandard)

# simulate data
set.seed(2023)
simulated_data <- simstandard::sim_standardized(sem_model_simulation, n = 100000)
# Schneider's tutorial
# https://cran.r-project.org/web/packages/simstandard/vignettes/simstandard_tutorial.html
# has a really nice "ggcor" function to display matrices:
ggcor <- function(d) {
  require(ggplot2)
  as.data.frame(d) %>%
    tibble::rownames_to_column("rowname") %>%
    tidyr::pivot_longer(-rowname, names_to = "colname", values_to = "r") %>%
    dplyr::mutate(rowname = forcats::fct_inorder(rowname) %>% forcats::fct_rev()) %>% 
    dplyr::mutate(colname = factor(colname, 
                                   levels = rev(levels(rowname)))) %>% 
    ggplot(aes(colname, rowname, fill = r)) +
    geom_tile(color = "lightgray") +
    geom_text(aes(label = formatC(r, digits = 2, format = "f") %>% 
                    stringr::str_replace_all("0\\.",".") %>% 
                    stringr::str_replace_all("1.00","1")), 
    color = "white", 
    fontface = "bold",
    family = "serif") +
    scale_fill_gradient2(NULL,
                         na.value = "darkgrey",
                         limits = c(-1.01, 1.01),
                         high = "darkred",
                         low = "darkblue") +
    coord_equal() +
    scale_x_discrete(NULL,position = "top") +
    scale_y_discrete(NULL) +
    theme_light(base_family = "serif", base_size = 12) + 
    theme(axis.text.x = element_text(angle = 90))
}

# check covariances
# cov(simulated_data) # quite good match with the original results!
# a way lot easier to read 
cov(simulated_data) %>% ggcor() +
    labs(title="covariance matrix of the observed and latent variables")

# inspect the matrices (A, S) that simstandard uses to create the data
sem_model_simulation_matrices <- sim_standardized_matrices(sem_model_simulation)

# Reticular Action Model (RAM) by McArdle (1978)
# See Ferrer et al. (2019, pp. 126-142) chapter
# 
# A matrix contains all the asymmetric path coefficients (i.e., the loadings and the structural coefficients).
sem_model_simulation_matrices$RAM_matrices$A %>% ggcor() +
    labs(title="A matrix: loadings and the structural coefficients")

# S matrix contains all the symmetric path coefficients (i.e., the variances and correlations of the observed and latent variables)
sem_model_simulation_matrices$RAM_matrices$S %>% ggcor() +
    labs(title="S matrix: variances and correlations of the observed \n and latent variables")

We can see that the simulated data is close to the “sem_model_simulation” with fixed parameters:

# ENC =~ 0.81*v5   + 0.77*v7 + 0.87*v17  
# BUI =~ 0.67*v42r + 0.57*v43
# PSY =~ 0.90*v44  + 0.55*v45
# 
# PSY ~ -0.10*ENC + 0.85*BUI           
# 
# ENC ~~ -.30*BUI                        

Next, we'll see how the lavaan output with simulated data and non-fixed model compares to the simulation results.

# # this was the original "sem_model_simulation" model:
# #
# sem_model_simulation <- '
# 
# # Factors
# ENC =~ 0.81*v5   + 0.77*v7 + 0.87*v17   # standardized loadings from "Std.all" output above
# BUI =~ 0.67*v42r + 0.57*v43           
# PSY =~ 0.90*v44  + 0.55*v45               
# 
# # Regressions
# PSY ~ -0.10*ENC + 0.85*BUI              # standardized path coefficients from "Std.all" output above
# 
# # Covariances
# ENC ~~ -.30*BUI                         # covariance from "Std.all" output above
# '

# we'll make a new version of model where all fixed parameters are set free
sem_model_simulation_free <- simstandard::fixed2free(sem_model_simulation)

# # check
# cat(sem_model_simulation_free)
# ENC ~~ BUI
# PSY ~ ENC + BUI
# BUI =~ v42r + v43
# ENC =~ v5 + v7 + v17
# PSY =~ v44 + v45

#  actually, the resulting model is identical to our original model:
# sem_model <- '
# # Factors
# ENC =~ NA*v5 + v7 + 1*v17   # Encouraging leadership
# BUI =~ 1*v42r + v43         # Build-up of work requirements
# PSY =~ 1*v44 + v45          # Psychic stress of the work
# # Regressions
# PSY ~ ENC + BUI             # Predict PSY with ENC and BUI
# # Covariances
# ENC ~~ BUI                  # Let ENC and BUI correlate
# '


# we'll use lavaan to see if the observed data in "sem_model_simulation" conform to the model in "sem_model_simulation_free"

# create simulated data
set.seed(2023)
simulated_data2 <- simstandard::sim_standardized(sem_model_simulation, # or use "sem_model"
                                                 latent = F, # Note: only following vars are included: "v5", "v7", "v17", "v42r", "v43", "v44", "v45"
                                                 errors = F,
                                                 n = 100000)

# evaluate the fit of free model on simulated data
lavaan_fit1 <- sem(model = sem_model_simulation_free, 
      data = simulated_data2)

# see the results
summary(lavaan_fit1,
  standardized = T,
  fit.measures = T)
## lavaan 0.6.14 ended normally after 29 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        17
## 
##   Number of observations                        100000
## 
## Model Test User Model:
##                                                       
##   Test statistic                                10.908
##   Degrees of freedom                                11
##   P-value (Chi-square)                           0.451
## 
## Model Test Baseline Model:
## 
##   Test statistic                            235459.035
##   Degrees of freedom                                21
##   P-value                                        0.000
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    1.000
##   Tucker-Lewis Index (TLI)                       1.000
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)            -875614.620
##   Loglikelihood unrestricted model (H1)    -875609.166
##                                                       
##   Akaike (AIC)                             1751263.240
##   Bayesian (BIC)                           1751424.959
##   Sample-size adjusted Bayesian (SABIC)    1751370.933
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.000
##   90 Percent confidence interval - lower         0.000
##   90 Percent confidence interval - upper         0.003
##   P-value H_0: RMSEA <= 0.050                    1.000
##   P-value H_0: RMSEA >= 0.080                    0.000
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.001
## 
## 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
##   BUI =~                                                                
##     v42r              1.000                               0.672    0.671
##     v43               0.850    0.006  140.143    0.000    0.571    0.573
##   ENC =~                                                                
##     v5                1.000                               0.811    0.811
##     v7                0.952    0.004  251.582    0.000    0.772    0.770
##     v17               1.074    0.004  269.927    0.000    0.871    0.870
##   PSY =~                                                                
##     v44               1.000                               0.897    0.897
##     v45               0.608    0.004  136.737    0.000    0.545    0.547
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   PSY ~                                                                 
##     ENC              -0.116    0.004  -27.082    0.000   -0.105   -0.105
##     BUI               1.139    0.009  125.759    0.000    0.853    0.853
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   BUI ~~                                                                
##     ENC              -0.162    0.003  -62.765    0.000   -0.297   -0.297
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v42r              0.551    0.004  142.768    0.000    0.551    0.549
##    .v43               0.669    0.004  181.689    0.000    0.669    0.672
##    .v5                0.341    0.002  147.360    0.000    0.341    0.342
##    .v7                0.410    0.002  168.832    0.000    0.410    0.408
##    .v17               0.244    0.002  107.338    0.000    0.244    0.243
##    .v44               0.196    0.005   41.525    0.000    0.196    0.196
##    .v45               0.696    0.004  195.755    0.000    0.696    0.701
##     BUI               0.452    0.005   94.492    0.000    1.000    1.000
##     ENC               0.658    0.005  144.705    0.000    1.000    1.000
##    .PSY               0.167    0.006   28.828    0.000    0.208    0.208
# extract RAM paths
sem_model_simulation_free_matrices <- simstandard::lav2ram(lavaan_fit1)

# display asymmetric paths (i.e., single-headed arrows for loadings and structure coefficients)
sem_model_simulation_free_matrices$A %>% ggcor() +
    labs(title="A matrix: loadings and the structural coefficients")

# display symmetric paths (i.e., curved double-headed arrows exogenous variances, error variances, disturbance variances, and any covariances among these)
sem_model_simulation_free_matrices$S %>% ggcor() +
    labs(title="S matrix: variances and correlations of the observed \n and latent variables")

lavaan results with the simulation data match the results of model with fixed parameters:

# ENC =~ 0.81*v5   + 0.77*v7 + 0.87*v17
# BUI =~ 0.67*v42r + 0.57*v43           
# PSY =~ 0.90*v44  + 0.55*v45               
# 
# PSY ~ -0.10*ENC + 0.85*BUI       
# 
# ENC ~~ -.30*BUI                

So, we are happy!

Next, let's look how lavaan::simulateData can produce simulated data.

library(lavaan)

# compare to simstandard::sim_standardized

# define simulated measurement model (same as before)
sem_model_simulation <- '

# Factors
ENC =~ 0.81*v5   + 0.77*v7 + 0.87*v17   # standardized loadings from "Std.all" output above
BUI =~ 0.67*v42r + 0.57*v43
PSY =~ 0.90*v44  + 0.55*v45

# Regressions
PSY ~ -0.10*ENC + 0.85*BUI              # standardized path coefficients from "Std.all" output above

# Covariances
ENC ~~ -.30*BUI                         # covariance from "Std.all" output above
'

# simulate 100 data frame rows
set.seed(2013)
simData_lavaan <- lavaan::simulateData(
  sem_model_simulation, 
  standardized = T, # known issue to produce variances exceeding 2 if set to TRUE
                    # see https://github.com/yrosseel/lavaan/issues/46
  sample.nobs=1000000
  )
nrow(simData_lavaan)
## [1] 1000000
# define measurement model
sem_model <- '
# Factors
ENC =~ NA*v5 + v7 + 1*v17   # Encouraging leadership
BUI =~ 1*v42r + v43         # Build-up of work requirements
PSY =~ 1*v44 + v45          # Psychic stress of the work
# Regressions
PSY ~ ENC + BUI             # Predict PSY with ENC and BUI
# Covariances
ENC ~~ BUI                  # Let ENC and BUI correlate
'

# fit the model on simulated data
lavaan_fit2 <- sem(sem_model, data=simData_lavaan)

# print the summary
summary(lavaan_fit2, standardized = T, fit.measures = T)
## lavaan 0.6.14 ended normally after 30 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        17
## 
##   Number of observations                       1000000
## 
## Model Test User Model:
##                                                       
##   Test statistic                                13.945
##   Degrees of freedom                                11
##   P-value (Chi-square)                           0.236
## 
## Model Test Baseline Model:
## 
##   Test statistic                           2349574.554
##   Degrees of freedom                                21
##   P-value                                        0.000
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    1.000
##   Tucker-Lewis Index (TLI)                       1.000
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)           -8757642.574
##   Loglikelihood unrestricted model (H1)   -8757635.601
##                                                       
##   Akaike (AIC)                            17515319.147
##   Bayesian (BIC)                          17515520.011
##   Sample-size adjusted Bayesian (SABIC)   17515465.984
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.001
##   90 Percent confidence interval - lower         0.000
##   90 Percent confidence interval - upper         0.001
##   P-value H_0: RMSEA <= 0.050                    1.000
##   P-value H_0: RMSEA >= 0.080                    0.000
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.001
## 
## 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
##   ENC =~                                                                
##     v5                0.930    0.001  852.061    0.000    0.810    0.810
##     v7                0.885    0.001  817.830    0.000    0.771    0.771
##     v17               1.000                               0.871    0.871
##   BUI =~                                                                
##     v42r              1.000                               0.668    0.669
##     v43               0.853    0.002  439.447    0.000    0.570    0.570
##   PSY =~                                                                
##     v44               1.000                               0.899    0.900
##     v45               0.611    0.001  431.722    0.000    0.549    0.549
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   PSY ~                                                                 
##     ENC              -0.103    0.001  -80.620    0.000   -0.099   -0.099
##     BUI               1.145    0.003  392.682    0.000    0.851    0.851
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC ~~                                                                
##     BUI              -0.175    0.001 -201.168    0.000   -0.300   -0.300
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5                0.345    0.001  469.008    0.000    0.345    0.344
##    .v7                0.407    0.001  532.417    0.000    0.407    0.406
##    .v17               0.243    0.001  337.703    0.000    0.243    0.242
##    .v42r              0.552    0.001  451.761    0.000    0.552    0.553
##    .v43               0.675    0.001  575.043    0.000    0.675    0.675
##    .v44               0.190    0.002  126.262    0.000    0.190    0.190
##    .v45               0.698    0.001  616.892    0.000    0.698    0.698
##     ENC               0.759    0.002  501.915    0.000    1.000    1.000
##     BUI               0.446    0.002  296.434    0.000    1.000    1.000
##    .PSY               0.174    0.002   94.011    0.000    0.216    0.216
# Latent Variables:
#                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
#   ENC =~                                                                
#     v5                0.930    0.001  852.061    0.000    0.810    0.810
#     v7                0.885    0.001  817.830    0.000    0.771    0.771
#     v17               1.000                               0.871    0.871
#   BUI =~                                                                
#     v42r              1.000                               0.668    0.669
#     v43               0.853    0.002  439.447    0.000    0.570    0.570
#   PSY =~                                                                
#     v44               1.000                               0.899    0.900
#     v45               0.611    0.001  431.722    0.000    0.549    0.549
# 
# Regressions:
#                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
#   PSY ~                                                                 
#     ENC              -0.103    0.001  -80.620    0.000   -0.099   -0.099
#     BUI               1.145    0.003  392.682    0.000    0.851    0.851
# 
# Covariances:
#                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
#   ENC ~~                                                                
#     BUI              -0.175    0.001 -201.168    0.000   -0.300   -0.300
# extract RAM paths
lavaan_sem_model_simulated_matrices <- simstandard::lav2ram(lavaan_fit2)

# display asymmetric paths (i.e., single-headed arrows for loadings and structure coefficients)
sem_model_simulation_free_matrices$A %>% ggcor() +
    labs(title="A matrix (simstandard): loadings and the structural coefficients")

lavaan_sem_model_simulated_matrices$A %>% ggcor() +
    labs(title="A matrix (lavaan): loadings and the structural coefficients")

# display symmetric paths (i.e., curved double-headed arrows exogenous variances, error variances, disturbance variances, and any covariances among these)
sem_model_simulation_free_matrices$S %>% ggcor() +
    labs(title="S matrix (simstandard): variances and correlations of the observed \n and latent variables")

lavaan_sem_model_simulated_matrices$S %>% ggcor() +
    labs(title="S matrix (lavaan): variances and correlations of the observed \n and latent variables")

lavaan simulation matches the simstandard results.

Next, we proceed with grouped SEM simulation using lavaan::simulateData.

library(lavaan)

# create three groups, each with 200 observations

# define population model for the simulated data (we'll use the same model as before)
sem_model_simulation <- '

# Factors
ENC =~ 0.81*v5   + 0.77*v7 + 0.87*v17   
BUI =~ 0.67*v42r + 0.57*v43
PSY =~ 0.90*v44  + 0.55*v45

# Regressions
PSY ~ -0.10*ENC + 0.85*BUI              

# Covariances
ENC ~~ -.30*BUI                         
'

# create simulated multi-group data based on the population model
set.seed(2023)
sim_multiGroupData_lavaan <- lavaan::simulateData(sem_model_simulation, 
                         sample.nobs=c(200,200,200), # add "group" variable
                         standardized = T,
                         return.type = "data.frame")

sem_multiGroup_model <- '
# Factors
ENC =~ NA*v5 + v7 + 1*v17   # Encouraging leadership
BUI =~ 1*v42r + v43         # Build-up of work requirements
PSY =~ 1*v44 + v45          # Psychic stress of the work
# Regressions
PSY ~ ENC + BUI             # Predict PSY with ENC and BUI
# Covariances
ENC ~~ BUI                  # Let ENC and BUI correlate
'
# need to check that variances do not exceed 1

lavaan_mg_mi_fit1 <- sem(sem_multiGroup_model, 
           # group = "group",
           data = sim_multiGroupData_lavaan)

# extract RAM paths
lavaan_mg_simulation_free_matrices <- simstandard::lav2ram(lavaan_mg_mi_fit1)

# display asymmetric paths (i.e., single-headed arrows for loadings and structure coefficients)
lavaan_mg_simulation_free_matrices$A %>% ggcor() +
    labs(title="A matrix: loadings and the structural coefficients")

# display symmetric paths (i.e., curved double-headed arrows exogenous variances, error variances, disturbance variances, and any covariances among these)
lavaan_mg_simulation_free_matrices$S %>% ggcor() +
    labs(title="S matrix: variances and correlations of the observed \n and latent variables")

# fit multi-group model and test measurement invariance (MI) using CFA

cfa_multiGroup_model <- '
# Factors
ENC =~ NA*v5 + v7 + 1*v17   # Encouraging leadership
BUI =~ 1*v42r + v43         # Build-up of work requirements
PSY =~ 1*v44 + v45          # Psychic stress of the work

# Correlations
ENC ~~ BUI
ENC ~~ PSY
BUI ~~ PSY
'


# -------------------------
# 1. configural invariance: the same factor structure is imposed on all groups
lavaan_mg_mi_fit1conf <- cfa(cfa_multiGroup_model, 
           group = "group",
           data = sim_multiGroupData_lavaan)

summary(lavaan_mg_mi_fit1conf, fit.measures = TRUE, standardized = TRUE)
## lavaan 0.6.14 ended normally after 48 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        72
## 
##   Number of observations per group:                   
##     1                                              200
##     2                                              200
##     3                                              200
## 
## Model Test User Model:
##                                                       
##   Test statistic                                33.939
##   Degrees of freedom                                33
##   P-value (Chi-square)                           0.422
##   Test statistic for each group:
##     1                                           13.813
##     2                                           11.823
##     3                                            8.303
## 
## Model Test Baseline Model:
## 
##   Test statistic                              1504.518
##   Degrees of freedom                                63
##   P-value                                        0.000
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    0.999
##   Tucker-Lewis Index (TLI)                       0.999
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)              -5187.488
##   Loglikelihood unrestricted model (H1)      -5170.518
##                                                       
##   Akaike (AIC)                               10518.975
##   Bayesian (BIC)                             10835.554
##   Sample-size adjusted Bayesian (SABIC)      10606.974
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.012
##   90 Percent confidence interval - lower         0.000
##   90 Percent confidence interval - upper         0.054
##   P-value H_0: RMSEA <= 0.050                    0.925
##   P-value H_0: RMSEA >= 0.080                    0.001
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.031
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## 
## Group 1 [1]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC =~                                                                
##     v5                0.917    0.080   11.421    0.000    0.744    0.816
##     v7                0.859    0.081   10.592    0.000    0.697    0.735
##     v17               1.000                               0.812    0.854
##   BUI =~                                                                
##     v42r              1.000                               0.803    0.734
##     v43               0.730    0.119    6.150    0.000    0.587    0.555
##   PSY =~                                                                
##     v44               1.000                               0.847    0.867
##     v45               0.592    0.099    5.998    0.000    0.501    0.527
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC ~~                                                                
##     BUI              -0.157    0.065   -2.409    0.016   -0.241   -0.241
##     PSY              -0.267    0.064   -4.175    0.000   -0.388   -0.388
##   BUI ~~                                                                
##     PSY               0.592    0.086    6.867    0.000    0.870    0.870
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5               -0.130    0.064   -2.019    0.044   -0.130   -0.143
##    .v7               -0.055    0.067   -0.818    0.413   -0.055   -0.058
##    .v17              -0.001    0.067   -0.022    0.983   -0.001   -0.002
##    .v42r              0.074    0.077    0.957    0.339    0.074    0.068
##    .v43               0.163    0.075    2.178    0.029    0.163    0.154
##    .v44               0.153    0.069    2.211    0.027    0.153    0.156
##    .v45               0.072    0.067    1.069    0.285    0.072    0.076
##     ENC               0.000                               0.000    0.000
##     BUI               0.000                               0.000    0.000
##     PSY               0.000                               0.000    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5                0.277    0.046    6.093    0.000    0.277    0.334
##    .v7                0.412    0.052    7.871    0.000    0.412    0.459
##    .v17               0.244    0.049    4.958    0.000    0.244    0.270
##    .v42r              0.554    0.108    5.137    0.000    0.554    0.462
##    .v43               0.772    0.092    8.425    0.000    0.772    0.692
##    .v44               0.236    0.098    2.418    0.016    0.236    0.248
##    .v45               0.652    0.073    8.912    0.000    0.652    0.722
##     ENC               0.659    0.097    6.805    0.000    1.000    1.000
##     BUI               0.646    0.141    4.577    0.000    1.000    1.000
##     PSY               0.717    0.132    5.421    0.000    1.000    1.000
## 
## 
## Group 2 [2]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC =~                                                                
##     v5                1.004    0.076   13.231    0.000    0.877    0.887
##     v7                0.797    0.074   10.793    0.000    0.697    0.705
##     v17               1.000                               0.874    0.856
##   BUI =~                                                                
##     v42r              1.000                               0.727    0.760
##     v43               0.763    0.106    7.184    0.000    0.554    0.601
##   PSY =~                                                                
##     v44               1.000                               0.838    0.753
##     v45               0.731    0.092    7.926    0.000    0.612    0.609
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC ~~                                                                
##     BUI              -0.181    0.061   -2.955    0.003   -0.285   -0.285
##     PSY              -0.410    0.078   -5.265    0.000   -0.560   -0.560
##   BUI ~~                                                                
##     PSY               0.601    0.085    7.057    0.000    0.988    0.988
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5                0.070    0.070    0.994    0.320    0.070    0.070
##    .v7                0.049    0.070    0.707    0.480    0.049    0.050
##    .v17               0.023    0.072    0.318    0.751    0.023    0.022
##    .v42r             -0.094    0.068   -1.394    0.163   -0.094   -0.099
##    .v43              -0.003    0.065   -0.040    0.968   -0.003   -0.003
##    .v44              -0.013    0.079   -0.171    0.864   -0.013   -0.012
##    .v45              -0.005    0.071   -0.077    0.938   -0.005   -0.005
##     ENC               0.000                               0.000    0.000
##     BUI               0.000                               0.000    0.000
##     PSY               0.000                               0.000    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5                0.209    0.047    4.450    0.000    0.209    0.214
##    .v7                0.492    0.057    8.633    0.000    0.492    0.503
##    .v17               0.279    0.050    5.523    0.000    0.279    0.267
##    .v42r              0.387    0.072    5.356    0.000    0.387    0.423
##    .v43               0.544    0.065    8.371    0.000    0.544    0.639
##    .v44               0.537    0.089    6.056    0.000    0.537    0.433
##    .v45               0.635    0.074    8.601    0.000    0.635    0.629
##     ENC               0.764    0.109    7.015    0.000    1.000    1.000
##     BUI               0.528    0.103    5.130    0.000    1.000    1.000
##     PSY               0.702    0.132    5.315    0.000    1.000    1.000
## 
## 
## Group 3 [3]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC =~                                                                
##     v5                0.935    0.077   12.111    0.000    0.761    0.800
##     v7                0.981    0.081   12.034    0.000    0.798    0.794
##     v17               1.000                               0.814    0.872
##   BUI =~                                                                
##     v42r              1.000                               0.779    0.741
##     v43               0.794    0.117    6.768    0.000    0.618    0.598
##   PSY =~                                                                
##     v44               1.000                               0.916    0.923
##     v45               0.598    0.097    6.156    0.000    0.547    0.549
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC ~~                                                                
##     BUI              -0.162    0.062   -2.616    0.009   -0.256   -0.256
##     PSY              -0.228    0.064   -3.577    0.000   -0.306   -0.306
##   BUI ~~                                                                
##     PSY               0.595    0.085    7.014    0.000    0.835    0.835
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5                0.067    0.067    0.996    0.319    0.067    0.070
##    .v7               -0.023    0.071   -0.331    0.741   -0.023   -0.023
##    .v17               0.084    0.066    1.268    0.205    0.084    0.090
##    .v42r             -0.064    0.074   -0.861    0.389   -0.064   -0.061
##    .v43              -0.113    0.073   -1.544    0.123   -0.113   -0.109
##    .v44              -0.124    0.070   -1.770    0.077   -0.124   -0.125
##    .v45              -0.064    0.070   -0.906    0.365   -0.064   -0.064
##     ENC               0.000                               0.000    0.000
##     BUI               0.000                               0.000    0.000
##     PSY               0.000                               0.000    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5                0.325    0.047    6.974    0.000    0.325    0.360
##    .v7                0.373    0.052    7.119    0.000    0.373    0.369
##    .v17               0.209    0.043    4.836    0.000    0.209    0.240
##    .v42r              0.499    0.092    5.433    0.000    0.499    0.451
##    .v43               0.688    0.084    8.172    0.000    0.688    0.643
##    .v44               0.147    0.107    1.371    0.171    0.147    0.149
##    .v45               0.692    0.079    8.774    0.000    0.692    0.698
##     ENC               0.662    0.093    7.143    0.000    1.000    1.000
##     BUI               0.607    0.125    4.848    0.000    1.000    1.000
##     PSY               0.838    0.144    5.825    0.000    1.000    1.000
# fitMeasures(lavaan_mg_mi_fit1conf)

# ----------------------------
# 2. metric (weak) invariance: the factor loadings are constrained to be equal across groups
lavaan_mg_mi_fit2metric <- cfa(cfa_multiGroup_model, 
           group = "group", 
           group.equal = c("loadings"),
           data = sim_multiGroupData_lavaan)

summary(lavaan_mg_mi_fit2metric, fit.measures = TRUE, standardized = TRUE)
## lavaan 0.6.14 ended normally after 41 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        72
##   Number of equality constraints                     8
## 
##   Number of observations per group:                   
##     1                                              200
##     2                                              200
##     3                                              200
## 
## Model Test User Model:
##                                                       
##   Test statistic                                41.022
##   Degrees of freedom                                41
##   P-value (Chi-square)                           0.470
##   Test statistic for each group:
##     1                                           14.436
##     2                                           15.373
##     3                                           11.212
## 
## Model Test Baseline Model:
## 
##   Test statistic                              1504.518
##   Degrees of freedom                                63
##   P-value                                        0.000
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    1.000
##   Tucker-Lewis Index (TLI)                       1.000
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)              -5191.029
##   Loglikelihood unrestricted model (H1)      -5170.518
##                                                       
##   Akaike (AIC)                               10510.058
##   Bayesian (BIC)                             10791.462
##   Sample-size adjusted Bayesian (SABIC)      10588.279
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.002
##   90 Percent confidence interval - lower         0.000
##   90 Percent confidence interval - upper         0.048
##   P-value H_0: RMSEA <= 0.050                    0.959
##   P-value H_0: RMSEA >= 0.080                    0.000
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.038
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## 
## Group 1 [1]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC =~                                                                
##     v5      (.p1.)    0.955    0.045   21.303    0.000    0.760    0.826
##     v7      (.p2.)    0.876    0.045   19.326    0.000    0.698    0.736
##     v17               1.000                               0.796    0.845
##   BUI =~                                                                
##     v42r              1.000                               0.789    0.723
##     v43     (.p5.)    0.766    0.066   11.643    0.000    0.604    0.568
##   PSY =~                                                                
##     v44               1.000                               0.822    0.846
##     v45     (.p7.)    0.650    0.055   11.859    0.000    0.534    0.555
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC ~~                                                                
##     BUI              -0.153    0.063   -2.436    0.015   -0.243   -0.243
##     PSY              -0.254    0.061   -4.165    0.000   -0.388   -0.388
##   BUI ~~                                                                
##     PSY               0.578    0.081    7.141    0.000    0.891    0.891
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5               -0.130    0.065   -2.001    0.045   -0.130   -0.141
##    .v7               -0.055    0.067   -0.818    0.413   -0.055   -0.058
##    .v17              -0.001    0.067   -0.022    0.982   -0.001   -0.002
##    .v42r              0.074    0.077    0.961    0.337    0.074    0.068
##    .v43               0.163    0.075    2.165    0.030    0.163    0.153
##    .v44               0.153    0.069    2.222    0.026    0.153    0.157
##    .v45               0.072    0.068    1.056    0.291    0.072    0.075
##     ENC               0.000                               0.000    0.000
##     BUI               0.000                               0.000    0.000
##     PSY               0.000                               0.000    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5                0.268    0.042    6.376    0.000    0.268    0.317
##    .v7                0.411    0.051    8.107    0.000    0.411    0.458
##    .v17               0.255    0.043    5.862    0.000    0.255    0.287
##    .v42r              0.568    0.099    5.749    0.000    0.568    0.477
##    .v43               0.765    0.090    8.499    0.000    0.765    0.677
##    .v44               0.268    0.079    3.407    0.001    0.268    0.284
##    .v45               0.641    0.071    8.991    0.000    0.641    0.692
##     ENC               0.634    0.081    7.825    0.000    1.000    1.000
##     BUI               0.622    0.121    5.160    0.000    1.000    1.000
##     PSY               0.676    0.111    6.098    0.000    1.000    1.000
## 
## 
## Group 2 [2]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC =~                                                                
##     v5      (.p1.)    0.955    0.045   21.303    0.000    0.838    0.866
##     v7      (.p2.)    0.876    0.045   19.326    0.000    0.769    0.743
##     v17               1.000                               0.878    0.861
##   BUI =~                                                                
##     v42r              1.000                               0.725    0.758
##     v43     (.p5.)    0.766    0.066   11.643    0.000    0.555    0.602
##   PSY =~                                                                
##     v44               1.000                               0.868    0.769
##     v45     (.p7.)    0.650    0.055   11.859    0.000    0.564    0.574
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC ~~                                                                
##     BUI              -0.183    0.061   -3.006    0.003   -0.288   -0.288
##     PSY              -0.425    0.078   -5.438    0.000   -0.558   -0.558
##   BUI ~~                                                                
##     PSY               0.620    0.083    7.455    0.000    0.985    0.985
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5                0.070    0.068    1.017    0.309    0.070    0.072
##    .v7                0.049    0.073    0.675    0.500    0.049    0.048
##    .v17               0.023    0.072    0.318    0.751    0.023    0.022
##    .v42r             -0.094    0.068   -1.394    0.163   -0.094   -0.099
##    .v43              -0.003    0.065   -0.040    0.968   -0.003   -0.003
##    .v44              -0.013    0.080   -0.168    0.866   -0.013   -0.012
##    .v45              -0.005    0.069   -0.079    0.937   -0.005   -0.006
##     ENC               0.000                               0.000    0.000
##     BUI               0.000                               0.000    0.000
##     PSY               0.000                               0.000    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5                0.234    0.041    5.757    0.000    0.234    0.250
##    .v7                0.479    0.057    8.375    0.000    0.479    0.447
##    .v17               0.269    0.045    5.929    0.000    0.269    0.259
##    .v42r              0.389    0.069    5.623    0.000    0.389    0.425
##    .v43               0.542    0.064    8.500    0.000    0.542    0.637
##    .v44               0.520    0.093    5.568    0.000    0.520    0.408
##    .v45               0.646    0.072    8.919    0.000    0.646    0.670
##     ENC               0.770    0.096    7.984    0.000    1.000    1.000
##     BUI               0.526    0.094    5.620    0.000    1.000    1.000
##     PSY               0.754    0.132    5.693    0.000    1.000    1.000
## 
## 
## Group 3 [3]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC =~                                                                
##     v5      (.p1.)    0.955    0.045   21.303    0.000    0.791    0.814
##     v7      (.p2.)    0.876    0.045   19.326    0.000    0.726    0.753
##     v17               1.000                               0.829    0.882
##   BUI =~                                                                
##     v42r              1.000                               0.789    0.748
##     v43     (.p5.)    0.766    0.066   11.643    0.000    0.604    0.588
##   PSY =~                                                                
##     v44               1.000                               0.892    0.901
##     v45     (.p7.)    0.650    0.055   11.859    0.000    0.579    0.575
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC ~~                                                                
##     BUI              -0.166    0.063   -2.631    0.009   -0.254   -0.254
##     PSY              -0.232    0.064   -3.631    0.000   -0.314   -0.314
##   BUI ~~                                                                
##     PSY               0.596    0.082    7.290    0.000    0.847    0.847
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5                0.067    0.069    0.974    0.330    0.067    0.069
##    .v7               -0.023    0.068   -0.344    0.731   -0.023   -0.024
##    .v17               0.084    0.066    1.259    0.208    0.084    0.089
##    .v42r             -0.064    0.075   -0.857    0.391   -0.064   -0.061
##    .v43              -0.113    0.073   -1.553    0.120   -0.113   -0.110
##    .v44              -0.124    0.070   -1.776    0.076   -0.124   -0.126
##    .v45              -0.064    0.071   -0.895    0.371   -0.064   -0.063
##     ENC               0.000                               0.000    0.000
##     BUI               0.000                               0.000    0.000
##     PSY               0.000                               0.000    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5                0.318    0.046    6.954    0.000    0.318    0.337
##    .v7                0.403    0.050    8.085    0.000    0.403    0.433
##    .v17               0.197    0.040    4.901    0.000    0.197    0.223
##    .v42r              0.491    0.089    5.530    0.000    0.491    0.441
##    .v43               0.693    0.082    8.473    0.000    0.693    0.655
##    .v44               0.183    0.081    2.251    0.024    0.183    0.187
##    .v45               0.679    0.076    8.968    0.000    0.679    0.669
##     ENC               0.687    0.085    8.077    0.000    1.000    1.000
##     BUI               0.623    0.114    5.444    0.000    1.000    1.000
##     PSY               0.795    0.120    6.626    0.000    1.000    1.000
# fitMeasures(lavaan_mg_mi_fit2weak)

# ------------------------------
# 3. scalar (strong) invariance: the factor loadings and intercepts are constrained to be equal across groups
lavaan_mg_mi_fit3scalar <- cfa(cfa_multiGroup_model, 
           group = "group", 
           group.equal = c("intercepts", "loadings"),
           data = sim_multiGroupData_lavaan)

summary(lavaan_mg_mi_fit3scalar, fit.measures = TRUE, standardized = TRUE)
## lavaan 0.6.14 ended normally after 48 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        78
##   Number of equality constraints                    22
## 
##   Number of observations per group:                   
##     1                                              200
##     2                                              200
##     3                                              200
## 
## Model Test User Model:
##                                                       
##   Test statistic                                53.124
##   Degrees of freedom                                49
##   P-value (Chi-square)                           0.318
##   Test statistic for each group:
##     1                                           19.518
##     2                                           18.604
##     3                                           15.001
## 
## Model Test Baseline Model:
## 
##   Test statistic                              1504.518
##   Degrees of freedom                                63
##   P-value                                        0.000
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    0.997
##   Tucker-Lewis Index (TLI)                       0.996
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)              -5197.080
##   Loglikelihood unrestricted model (H1)      -5170.518
##                                                       
##   Akaike (AIC)                               10506.160
##   Bayesian (BIC)                             10752.388
##   Sample-size adjusted Bayesian (SABIC)      10574.604
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.021
##   90 Percent confidence interval - lower         0.000
##   90 Percent confidence interval - upper         0.051
##   P-value H_0: RMSEA <= 0.050                    0.939
##   P-value H_0: RMSEA >= 0.080                    0.000
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.041
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## 
## Group 1 [1]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC =~                                                                
##     v5      (.p1.)    0.963    0.045   21.257    0.000    0.763    0.825
##     v7      (.p2.)    0.879    0.046   19.276    0.000    0.696    0.736
##     v17               1.000                               0.792    0.841
##   BUI =~                                                                
##     v42r              1.000                               0.783    0.719
##     v43     (.p5.)    0.778    0.066   11.806    0.000    0.609    0.571
##   PSY =~                                                                
##     v44               1.000                               0.824    0.848
##     v45     (.p7.)    0.645    0.054   11.967    0.000    0.531    0.553
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC ~~                                                                
##     BUI              -0.152    0.062   -2.444    0.015   -0.245   -0.245
##     PSY              -0.254    0.061   -4.173    0.000   -0.389   -0.389
##   BUI ~~                                                                
##     PSY               0.575    0.081    7.138    0.000    0.892    0.892
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5      (.21.)   -0.072    0.061   -1.184    0.237   -0.072   -0.078
##    .v7      (.22.)   -0.079    0.058   -1.361    0.174   -0.079   -0.084
##    .v17     (.23.)   -0.041    0.063   -0.654    0.513   -0.041   -0.044
##    .v42r    (.24.)    0.101    0.073    1.385    0.166    0.101    0.093
##    .v43     (.25.)    0.117    0.062    1.887    0.059    0.117    0.110
##    .v44     (.26.)    0.147    0.068    2.170    0.030    0.147    0.151
##    .v45     (.27.)    0.092    0.054    1.720    0.085    0.092    0.096
##     ENC               0.000                               0.000    0.000
##     BUI               0.000                               0.000    0.000
##     PSY               0.000                               0.000    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5                0.273    0.043    6.372    0.000    0.273    0.319
##    .v7                0.411    0.051    8.089    0.000    0.411    0.459
##    .v17               0.259    0.044    5.923    0.000    0.259    0.293
##    .v42r              0.574    0.098    5.847    0.000    0.574    0.484
##    .v43               0.766    0.090    8.464    0.000    0.766    0.674
##    .v44               0.266    0.079    3.365    0.001    0.266    0.282
##    .v45               0.642    0.071    9.008    0.000    0.642    0.695
##     ENC               0.627    0.080    7.798    0.000    1.000    1.000
##     BUI               0.613    0.119    5.148    0.000    1.000    1.000
##     PSY               0.679    0.111    6.102    0.000    1.000    1.000
## 
## 
## Group 2 [2]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC =~                                                                
##     v5      (.p1.)    0.963    0.045   21.257    0.000    0.841    0.867
##     v7      (.p2.)    0.879    0.046   19.276    0.000    0.768    0.743
##     v17               1.000                               0.874    0.857
##   BUI =~                                                                
##     v42r              1.000                               0.721    0.755
##     v43     (.p5.)    0.778    0.066   11.806    0.000    0.561    0.606
##   PSY =~                                                                
##     v44               1.000                               0.870    0.770
##     v45     (.p7.)    0.645    0.054   11.967    0.000    0.561    0.572
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC ~~                                                                
##     BUI              -0.183    0.061   -3.018    0.003   -0.290   -0.290
##     PSY              -0.424    0.078   -5.435    0.000   -0.558   -0.558
##   BUI ~~                                                                
##     PSY               0.618    0.083    7.456    0.000    0.986    0.986
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5      (.21.)   -0.072    0.061   -1.184    0.237   -0.072   -0.074
##    .v7      (.22.)   -0.079    0.058   -1.361    0.174   -0.079   -0.077
##    .v17     (.23.)   -0.041    0.063   -0.654    0.513   -0.041   -0.040
##    .v42r    (.24.)    0.101    0.073    1.385    0.166    0.101    0.106
##    .v43     (.25.)    0.117    0.062    1.887    0.059    0.117    0.126
##    .v44     (.26.)    0.147    0.068    2.170    0.030    0.147    0.130
##    .v45     (.27.)    0.092    0.054    1.720    0.085    0.092    0.094
##     ENC               0.114    0.090    1.275    0.202    0.131    0.131
##     BUI              -0.182    0.095   -1.921    0.055   -0.253   -0.253
##     PSY              -0.158    0.101   -1.561    0.119   -0.182   -0.182
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5                0.233    0.041    5.678    0.000    0.233    0.248
##    .v7                0.479    0.057    8.367    0.000    0.479    0.449
##    .v17               0.277    0.046    6.040    0.000    0.277    0.266
##    .v42r              0.393    0.069    5.719    0.000    0.393    0.431
##    .v43               0.541    0.064    8.461    0.000    0.541    0.633
##    .v44               0.519    0.094    5.528    0.000    0.519    0.407
##    .v45               0.647    0.072    8.934    0.000    0.647    0.673
##     ENC               0.763    0.096    7.954    0.000    1.000    1.000
##     BUI               0.520    0.093    5.617    0.000    1.000    1.000
##     PSY               0.757    0.133    5.697    0.000    1.000    1.000
## 
## 
## Group 3 [3]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC =~                                                                
##     v5      (.p1.)    0.963    0.045   21.257    0.000    0.795    0.816
##     v7      (.p2.)    0.879    0.046   19.276    0.000    0.726    0.751
##     v17               1.000                               0.826    0.880
##   BUI =~                                                                
##     v42r              1.000                               0.783    0.742
##     v43     (.p5.)    0.778    0.066   11.806    0.000    0.608    0.589
##   PSY =~                                                                
##     v44               1.000                               0.894    0.903
##     v45     (.p7.)    0.645    0.054   11.967    0.000    0.576    0.573
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC ~~                                                                
##     BUI              -0.165    0.063   -2.630    0.009   -0.255   -0.255
##     PSY              -0.231    0.064   -3.624    0.000   -0.313   -0.313
##   BUI ~~                                                                
##     PSY               0.594    0.081    7.289    0.000    0.849    0.849
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5      (.21.)   -0.072    0.061   -1.184    0.237   -0.072   -0.074
##    .v7      (.22.)   -0.079    0.058   -1.361    0.174   -0.079   -0.082
##    .v17     (.23.)   -0.041    0.063   -0.654    0.513   -0.041   -0.044
##    .v42r    (.24.)    0.101    0.073    1.385    0.166    0.101    0.096
##    .v43     (.25.)    0.117    0.062    1.887    0.059    0.117    0.113
##    .v44     (.26.)    0.147    0.068    2.170    0.030    0.147    0.149
##    .v45     (.27.)    0.092    0.054    1.720    0.085    0.092    0.092
##     ENC               0.119    0.087    1.361    0.174    0.144    0.144
##     BUI              -0.204    0.099   -2.056    0.040   -0.261   -0.261
##     PSY              -0.268    0.097   -2.776    0.005   -0.300   -0.300
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5                0.317    0.046    6.899    0.000    0.317    0.334
##    .v7                0.406    0.050    8.100    0.000    0.406    0.435
##    .v17               0.199    0.040    4.947    0.000    0.199    0.226
##    .v42r              0.500    0.089    5.647    0.000    0.500    0.449
##    .v43               0.698    0.083    8.449    0.000    0.698    0.653
##    .v44               0.181    0.082    2.207    0.027    0.181    0.184
##    .v45               0.680    0.076    8.987    0.000    0.680    0.672
##     ENC               0.682    0.085    8.063    0.000    1.000    1.000
##     BUI               0.612    0.113    5.415    0.000    1.000    1.000
##     PSY               0.799    0.120    6.634    0.000    1.000    1.000
# fitMeasures(lavaan_mg_mi_fit3scalar)

# --------------------------------
# 4. strict (residual) invariance: the factor loadings, intercepts and residuals are constrained to be equal across groups
lavaan_mg_mi_fit4strict <- cfa(cfa_multiGroup_model, 
           group = "group", 
           group.equal = c("intercepts", "loadings", "residuals"),
           data = sim_multiGroupData_lavaan)

summary(lavaan_mg_mi_fit4strict, fit.measures = TRUE, standardized = TRUE)
## lavaan 0.6.14 ended normally after 47 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        78
##   Number of equality constraints                    36
## 
##   Number of observations per group:                   
##     1                                              200
##     2                                              200
##     3                                              200
## 
## Model Test User Model:
##                                                       
##   Test statistic                                73.614
##   Degrees of freedom                                63
##   P-value (Chi-square)                           0.170
##   Test statistic for each group:
##     1                                           22.616
##     2                                           30.028
##     3                                           20.970
## 
## Model Test Baseline Model:
## 
##   Test statistic                              1504.518
##   Degrees of freedom                                63
##   P-value                                        0.000
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    0.993
##   Tucker-Lewis Index (TLI)                       0.993
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)              -5207.325
##   Loglikelihood unrestricted model (H1)      -5170.518
##                                                       
##   Akaike (AIC)                               10498.650
##   Bayesian (BIC)                             10683.321
##   Sample-size adjusted Bayesian (SABIC)      10549.983
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.029
##   90 Percent confidence interval - lower         0.000
##   90 Percent confidence interval - upper         0.054
##   P-value H_0: RMSEA <= 0.050                    0.914
##   P-value H_0: RMSEA >= 0.080                    0.000
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.043
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## 
## Group 1 [1]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC =~                                                                
##     v5      (.p1.)    0.962    0.046   21.131    0.000    0.764    0.826
##     v7      (.p2.)    0.874    0.046   19.158    0.000    0.694    0.726
##     v17               1.000                               0.794    0.848
##   BUI =~                                                                
##     v42r              1.000                               0.815    0.757
##     v43     (.p5.)    0.784    0.066   11.859    0.000    0.639    0.616
##   PSY =~                                                                
##     v44               1.000                               0.797    0.814
##     v45     (.p7.)    0.649    0.054   11.982    0.000    0.517    0.538
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC ~~                                                                
##     BUI              -0.151    0.062   -2.439    0.015   -0.234   -0.234
##     PSY              -0.249    0.061   -4.098    0.000   -0.394   -0.394
##   BUI ~~                                                                
##     PSY               0.574    0.080    7.133    0.000    0.883    0.883
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5      (.21.)   -0.072    0.061   -1.177    0.239   -0.072   -0.078
##    .v7      (.22.)   -0.077    0.058   -1.313    0.189   -0.077   -0.080
##    .v17     (.23.)   -0.042    0.063   -0.665    0.506   -0.042   -0.045
##    .v42r    (.24.)    0.101    0.073    1.387    0.165    0.101    0.094
##    .v43     (.25.)    0.117    0.062    1.874    0.061    0.117    0.113
##    .v44     (.26.)    0.146    0.068    2.150    0.032    0.146    0.149
##    .v45     (.27.)    0.092    0.053    1.732    0.083    0.092    0.096
##     ENC               0.000                               0.000    0.000
##     BUI               0.000                               0.000    0.000
##     PSY               0.000                               0.000    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5      (.11.)    0.272    0.027   10.016    0.000    0.272    0.317
##    .v7      (.12.)    0.434    0.031   13.855    0.000    0.434    0.474
##    .v17     (.13.)    0.247    0.028    8.906    0.000    0.247    0.282
##    .v42r    (.14.)    0.493    0.051    9.670    0.000    0.493    0.426
##    .v43     (.15.)    0.665    0.046   14.348    0.000    0.665    0.620
##    .v44     (.16.)    0.323    0.052    6.175    0.000    0.323    0.337
##    .v45     (.17.)    0.656    0.043   15.213    0.000    0.656    0.710
##     ENC               0.631    0.080    7.858    0.000    1.000    1.000
##     BUI               0.664    0.111    5.963    0.000    1.000    1.000
##     PSY               0.635    0.102    6.244    0.000    1.000    1.000
## 
## 
## Group 2 [2]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC =~                                                                
##     v5      (.p1.)    0.962    0.046   21.131    0.000    0.840    0.850
##     v7      (.p2.)    0.874    0.046   19.158    0.000    0.763    0.757
##     v17               1.000                               0.873    0.869
##   BUI =~                                                                
##     v42r              1.000                               0.671    0.691
##     v43     (.p5.)    0.784    0.066   11.859    0.000    0.526    0.542
##   PSY =~                                                                
##     v44               1.000                               0.936    0.855
##     v45     (.p7.)    0.649    0.054   11.982    0.000    0.608    0.600
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC ~~                                                                
##     BUI              -0.184    0.060   -3.042    0.002   -0.314   -0.314
##     PSY              -0.416    0.077   -5.383    0.000   -0.509   -0.509
##   BUI ~~                                                                
##     PSY               0.611    0.082    7.453    0.000    0.973    0.973
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5      (.21.)   -0.072    0.061   -1.177    0.239   -0.072   -0.073
##    .v7      (.22.)   -0.077    0.058   -1.313    0.189   -0.077   -0.076
##    .v17     (.23.)   -0.042    0.063   -0.665    0.506   -0.042   -0.042
##    .v42r    (.24.)    0.101    0.073    1.387    0.165    0.101    0.104
##    .v43     (.25.)    0.117    0.062    1.874    0.061    0.117    0.120
##    .v44     (.26.)    0.146    0.068    2.150    0.032    0.146    0.133
##    .v45     (.27.)    0.092    0.053    1.732    0.083    0.092    0.091
##     ENC               0.110    0.090    1.229    0.219    0.126    0.126
##     BUI              -0.182    0.095   -1.917    0.055   -0.271   -0.271
##     PSY              -0.158    0.101   -1.561    0.119   -0.169   -0.169
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5      (.11.)    0.272    0.027   10.016    0.000    0.272    0.278
##    .v7      (.12.)    0.434    0.031   13.855    0.000    0.434    0.427
##    .v17     (.13.)    0.247    0.028    8.906    0.000    0.247    0.245
##    .v42r    (.14.)    0.493    0.051    9.670    0.000    0.493    0.523
##    .v43     (.15.)    0.665    0.046   14.348    0.000    0.665    0.707
##    .v44     (.16.)    0.323    0.052    6.175    0.000    0.323    0.269
##    .v45     (.17.)    0.656    0.043   15.213    0.000    0.656    0.640
##     ENC               0.762    0.095    8.041    0.000    1.000    1.000
##     BUI               0.450    0.088    5.112    0.000    1.000    1.000
##     PSY               0.877    0.126    6.970    0.000    1.000    1.000
## 
## 
## Group 3 [3]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC =~                                                                
##     v5      (.p1.)    0.962    0.046   21.131    0.000    0.792    0.835
##     v7      (.p2.)    0.874    0.046   19.158    0.000    0.719    0.737
##     v17               1.000                               0.823    0.856
##   BUI =~                                                                
##     v42r              1.000                               0.786    0.746
##     v43     (.p5.)    0.784    0.066   11.859    0.000    0.616    0.603
##   PSY =~                                                                
##     v44               1.000                               0.835    0.826
##     v45     (.p7.)    0.649    0.054   11.982    0.000    0.542    0.556
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC ~~                                                                
##     BUI              -0.162    0.063   -2.592    0.010   -0.251   -0.251
##     PSY              -0.232    0.064   -3.627    0.000   -0.338   -0.338
##   BUI ~~                                                                
##     PSY               0.587    0.082    7.197    0.000    0.894    0.894
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5      (.21.)   -0.072    0.061   -1.177    0.239   -0.072   -0.076
##    .v7      (.22.)   -0.077    0.058   -1.313    0.189   -0.077   -0.079
##    .v17     (.23.)   -0.042    0.063   -0.665    0.506   -0.042   -0.043
##    .v42r    (.24.)    0.101    0.073    1.387    0.165    0.101    0.096
##    .v43     (.25.)    0.117    0.062    1.874    0.061    0.117    0.114
##    .v44     (.26.)    0.146    0.068    2.150    0.032    0.146    0.145
##    .v45     (.27.)    0.092    0.053    1.732    0.083    0.092    0.095
##     ENC               0.120    0.087    1.374    0.170    0.146    0.146
##     BUI              -0.205    0.099   -2.067    0.039   -0.261   -0.261
##     PSY              -0.265    0.097   -2.742    0.006   -0.318   -0.318
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5      (.11.)    0.272    0.027   10.016    0.000    0.272    0.302
##    .v7      (.12.)    0.434    0.031   13.855    0.000    0.434    0.456
##    .v17     (.13.)    0.247    0.028    8.906    0.000    0.247    0.268
##    .v42r    (.14.)    0.493    0.051    9.670    0.000    0.493    0.444
##    .v43     (.15.)    0.665    0.046   14.348    0.000    0.665    0.637
##    .v44     (.16.)    0.323    0.052    6.175    0.000    0.323    0.317
##    .v45     (.17.)    0.656    0.043   15.213    0.000    0.656    0.691
##     ENC               0.677    0.085    7.930    0.000    1.000    1.000
##     BUI               0.618    0.106    5.813    0.000    1.000    1.000
##     PSY               0.697    0.108    6.462    0.000    1.000    1.000
# fitMeasures(lavaan_mg_mi_fit4resid)
# test for significant differences between groups with chi-square test

# first, lavaan::lavTestLRT
lavaan::lavTestLRT(lavaan_mg_mi_fit1conf,lavaan_mg_mi_fit2metric,lavaan_mg_mi_fit3scalar,lavaan_mg_mi_fit4strict)
## 
## Chi-Squared Difference Test
## 
##                         Df   AIC   BIC  Chisq Chisq diff    RMSEA Df diff
## lavaan_mg_mi_fit1conf   33 10519 10836 33.939                            
## lavaan_mg_mi_fit2metric 41 10510 10792 41.022     7.0831 0.000000       8
## lavaan_mg_mi_fit3scalar 49 10506 10752 53.124    12.1020 0.050633       8
## lavaan_mg_mi_fit4strict 63 10499 10683 73.614    20.4899 0.048144      14
##                         Pr(>Chisq)
## lavaan_mg_mi_fit1conf             
## lavaan_mg_mi_fit2metric     0.5277
## lavaan_mg_mi_fit3scalar     0.1467
## lavaan_mg_mi_fit4strict     0.1154
# Chi-Squared Difference Test
# 
#                         Df   AIC   BIC  Chisq Chisq diff    RMSEA Df diff Pr(>Chisq)
# lavaan_mg_mi_fit1conf   33 10519 10836 33.939                                       
# lavaan_mg_mi_fit2metric 41 10510 10792 41.022     7.0831 0.000000       8     0.5277
# lavaan_mg_mi_fit3scalar 49 10506 10752 53.124    12.1020 0.050633       8     0.1467
# lavaan_mg_mi_fit4strict 63 10499 10683 73.614    20.4899 0.048144      14     0.1154

# second, more specific results from semTools::compareFit
library(semTools)
LRT_MI_result <- semTools::compareFit(lavaan_mg_mi_fit1conf,lavaan_mg_mi_fit2metric,lavaan_mg_mi_fit3scalar,lavaan_mg_mi_fit4strict)
summary(LRT_MI_result)
## ################### Nested Model Comparison #########################
## 
## Chi-Squared Difference Test
## 
##                         Df   AIC   BIC  Chisq Chisq diff    RMSEA Df diff
## lavaan_mg_mi_fit1conf   33 10519 10836 33.939                            
## lavaan_mg_mi_fit2metric 41 10510 10792 41.022     7.0831 0.000000       8
## lavaan_mg_mi_fit3scalar 49 10506 10752 53.124    12.1020 0.050633       8
## lavaan_mg_mi_fit4strict 63 10499 10683 73.614    20.4899 0.048144      14
##                         Pr(>Chisq)
## lavaan_mg_mi_fit1conf             
## lavaan_mg_mi_fit2metric     0.5277
## lavaan_mg_mi_fit3scalar     0.1467
## lavaan_mg_mi_fit4strict     0.1154
## 
## ####################### Model Fit Indices ###########################
##                           chisq df pvalue rmsea    cfi    tli  srmr        aic
## lavaan_mg_mi_fit1conf   33.939† 33   .422 .012  0.999  0.999  .031† 10518.975 
## lavaan_mg_mi_fit2metric 41.022  41   .470 .002† 1.000† 1.000† .038  10510.058 
## lavaan_mg_mi_fit3scalar 53.124  49   .318 .021  0.997  0.996  .041  10506.160 
## lavaan_mg_mi_fit4strict 73.614  63   .170 .029   .993   .993  .043  10498.650†
##                                bic
## lavaan_mg_mi_fit1conf   10835.554 
## lavaan_mg_mi_fit2metric 10791.462 
## lavaan_mg_mi_fit3scalar 10752.388 
## lavaan_mg_mi_fit4strict 10683.321†
## 
## ################## Differences in Fit Indices #######################
##                                                   df  rmsea    cfi    tli  srmr
## lavaan_mg_mi_fit2metric - lavaan_mg_mi_fit1conf    8 -0.010  0.001  0.001 0.007
## lavaan_mg_mi_fit3scalar - lavaan_mg_mi_fit2metric  8  0.019 -0.003 -0.004 0.003
## lavaan_mg_mi_fit4strict - lavaan_mg_mi_fit3scalar 14  0.009 -0.005 -0.004 0.002
##                                                      aic     bic
## lavaan_mg_mi_fit2metric - lavaan_mg_mi_fit1conf   -8.917 -44.092
## lavaan_mg_mi_fit3scalar - lavaan_mg_mi_fit2metric -3.898 -39.073
## lavaan_mg_mi_fit4strict - lavaan_mg_mi_fit3scalar -7.510 -69.067
# Chi-Squared Difference Test
# 
#                         Df   AIC   BIC  Chisq Chisq diff    RMSEA Df diff Pr(>Chisq)
# lavaan_mg_mi_fit1conf   33 10519 10836 33.939                                       
# lavaan_mg_mi_fit2metric 41 10510 10792 41.022     7.0831 0.000000       8     0.5277 # metric MI hold
# lavaan_mg_mi_fit3scalar 49 10506 10752 53.124    12.1020 0.050633       8     0.1467 # scalar MI holds
# lavaan_mg_mi_fit4strict 63 10499 10683 73.614    20.4899 0.048144      14     0.1154 # strict MI holds
# 
# ####################### Model Fit Indices ###########################
#                           chisq df pvalue rmsea    cfi    tli  srmr        aic        bic
# lavaan_mg_mi_fit1conf   33.939† 33   .422 .012  0.999  0.999  .031† 10518.975  10835.554   # configural MI holds
# lavaan_mg_mi_fit2metric 41.022  41   .470 .002† 1.000† 1.000† .038  10510.058  10791.462   # metric MI holds
# lavaan_mg_mi_fit3scalar 53.124  49   .318 .021  0.997  0.996  .041  10506.160  10752.388   # scalar MI holds
# lavaan_mg_mi_fit4strict 73.614  63   .170 .029   .993   .993  .043  10498.650† 10683.321†  # strict MI holds
# 
# ################## Differences in Fit Indices #######################
#                                                   df  rmsea    cfi    tli  srmr    aic     bic
# lavaan_mg_mi_fit2metric - lavaan_mg_mi_fit1conf    8 -0.010  0.001  0.001 0.007 -8.917 -44.092 # RMSEA and CFI delta ok 
# lavaan_mg_mi_fit3scalar - lavaan_mg_mi_fit2metric  8  0.019 -0.003 -0.004 0.003 -3.898 -39.073 # CFI delta ok
# lavaan_mg_mi_fit4strict - lavaan_mg_mi_fit3scalar 14  0.009 -0.005 -0.004 0.002 -7.510 -69.067 # RMSEA and DFI delta ok

# Note: Less than -.01 change in CFI, combined with less than .015 change in RMSEA is used as evidence for non-invariance
# Chen, F. F. (2007). Sensitivity of goodness of fit indexes to lack of measurement invariance. Structural Equation Modeling,  14(3), 464–504. 

Conclusion from measurement invariance tests: All four types on invariance are satisfied with this data.

Test if the three groups differ by their regressions

As we have established measurement invariance across the three groups in the mg simulation data, we may proceed to test if the these groups differ by their PSY ~ ENC and PSY ~ BUI regressions.

First, we will estimate the free model:

# earlier we created a simulated mg data ("sim_multiGroupData_lavaan") with three groups (each n = 200)

# we'll do it again:
# define population model for the simulated data
sem_model_simulation <- '

# Factors
ENC =~ 0.81*v5   + 0.77*v7 + 0.87*v17   
BUI =~ 0.67*v42r + 0.57*v43
PSY =~ 0.90*v44  + 0.55*v45

# Regressions
PSY ~ -0.10*ENC + 0.85*BUI              

# Covariances
ENC ~~ -.30*BUI                         
'

# create simulated multi-group data based on the population model
set.seed(2023)
sim_multiGroupData_lavaan <- lavaan::simulateData(sem_model_simulation, 
                         sample.nobs=c(200,200,200), # add "group" variable
                         standardized = T,
                         return.type = "data.frame")

# define SEM model
sem_multiGroup_model <- '
# Factors
ENC =~ NA*v5 + v7 + 1*v17   # Encouraging leadership
BUI =~ 1*v42r + v43         # Build-up of work requirements
PSY =~ 1*v44 + v45          # Psychic stress of the work
# Regressions
PSY ~ ENC + BUI             # Predict PSY with ENC and BUI
# Covariances
ENC ~~ BUI                  # Let ENC and BUI correlate
'

# fit the "free" model where the coefficients are allowed to vary across three groups
lavaan_mg_free <- sem(sem_multiGroup_model, 
           group = "group",
           data = sim_multiGroupData_lavaan)

# see the results
summary(lavaan_mg_free)
## lavaan 0.6.14 ended normally after 52 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        72
## 
##   Number of observations per group:                   
##     1                                              200
##     2                                              200
##     3                                              200
## 
## Model Test User Model:
##                                                       
##   Test statistic                                33.939
##   Degrees of freedom                                33
##   P-value (Chi-square)                           0.422
##   Test statistic for each group:
##     1                                           13.813
##     2                                           11.823
##     3                                            8.303
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## 
## Group 1 [1]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC =~                                              
##     v5                0.917    0.080   11.421    0.000
##     v7                0.859    0.081   10.592    0.000
##     v17               1.000                           
##   BUI =~                                              
##     v42r              1.000                           
##     v43               0.730    0.119    6.150    0.000
##   PSY =~                                              
##     v44               1.000                           
##     v45               0.592    0.099    5.998    0.000
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   PSY ~                                               
##     ENC              -0.197    0.084   -2.345    0.019
##     BUI               0.869    0.147    5.932    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC ~~                                              
##     BUI              -0.157    0.065   -2.409    0.016
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5               -0.130    0.064   -2.019    0.044
##    .v7               -0.055    0.067   -0.818    0.413
##    .v17              -0.001    0.067   -0.022    0.983
##    .v42r              0.074    0.077    0.957    0.339
##    .v43               0.163    0.075    2.178    0.029
##    .v44               0.153    0.069    2.210    0.027
##    .v45               0.072    0.067    1.069    0.285
##     ENC               0.000                           
##     BUI               0.000                           
##    .PSY               0.000                           
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5                0.277    0.046    6.093    0.000
##    .v7                0.412    0.052    7.871    0.000
##    .v17               0.244    0.049    4.958    0.000
##    .v42r              0.554    0.108    5.137    0.000
##    .v43               0.772    0.092    8.425    0.000
##    .v44               0.236    0.098    2.417    0.016
##    .v45               0.652    0.073    8.912    0.000
##     ENC               0.659    0.097    6.805    0.000
##     BUI               0.646    0.141    4.577    0.000
##    .PSY               0.150    0.113    1.332    0.183
## 
## 
## Group 2 [2]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC =~                                              
##     v5                1.004    0.076   13.231    0.000
##     v7                0.797    0.074   10.793    0.000
##     v17               1.000                           
##   BUI =~                                              
##     v42r              1.000                           
##     v43               0.763    0.106    7.184    0.000
##   PSY =~                                              
##     v44               1.000                           
##     v45               0.731    0.092    7.926    0.000
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   PSY ~                                               
##     ENC              -0.291    0.078   -3.735    0.000
##     BUI               1.039    0.154    6.753    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC ~~                                              
##     BUI              -0.181    0.061   -2.955    0.003
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5                0.070    0.070    0.994    0.320
##    .v7                0.049    0.070    0.707    0.480
##    .v17               0.023    0.072    0.318    0.751
##    .v42r             -0.094    0.068   -1.394    0.163
##    .v43              -0.003    0.065   -0.040    0.968
##    .v44              -0.013    0.079   -0.171    0.864
##    .v45              -0.005    0.071   -0.077    0.938
##     ENC               0.000                           
##     BUI               0.000                           
##    .PSY               0.000                           
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5                0.209    0.047    4.450    0.000
##    .v7                0.492    0.057    8.633    0.000
##    .v17               0.279    0.050    5.523    0.000
##    .v42r              0.387    0.072    5.355    0.000
##    .v43               0.544    0.065    8.371    0.000
##    .v44               0.537    0.089    6.056    0.000
##    .v45               0.635    0.074    8.601    0.000
##     ENC               0.764    0.109    7.015    0.000
##     BUI               0.528    0.103    5.130    0.000
##    .PSY              -0.042    0.087   -0.483    0.629
## 
## 
## Group 3 [3]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC =~                                              
##     v5                0.935    0.077   12.111    0.000
##     v7                0.981    0.081   12.034    0.000
##     v17               1.000                           
##   BUI =~                                              
##     v42r              1.000                           
##     v43               0.794    0.117    6.768    0.000
##   PSY =~                                              
##     v44               1.000                           
##     v45               0.598    0.097    6.156    0.000
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   PSY ~                                               
##     ENC              -0.111    0.085   -1.309    0.190
##     BUI               0.951    0.145    6.541    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC ~~                                              
##     BUI              -0.162    0.062   -2.616    0.009
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5                0.067    0.067    0.996    0.319
##    .v7               -0.023    0.071   -0.331    0.741
##    .v17               0.084    0.066    1.268    0.205
##    .v42r             -0.064    0.074   -0.861    0.389
##    .v43              -0.113    0.073   -1.544    0.123
##    .v44              -0.124    0.070   -1.770    0.077
##    .v45              -0.064    0.070   -0.906    0.365
##     ENC               0.000                           
##     BUI               0.000                           
##    .PSY               0.000                           
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5                0.325    0.047    6.974    0.000
##    .v7                0.373    0.052    7.119    0.000
##    .v17               0.209    0.043    4.836    0.000
##    .v42r              0.499    0.092    5.433    0.000
##    .v43               0.688    0.084    8.172    0.000
##    .v44               0.147    0.107    1.371    0.171
##    .v45               0.692    0.079    8.774    0.000
##     ENC               0.662    0.093    7.143    0.000
##     BUI               0.607    0.125    4.848    0.000
##    .PSY               0.247    0.125    1.971    0.049
# our interest is to see if there are differences across three groups in these regressions:

# Group 1
# Regressions:
#                    Estimate  Std.Err  z-value  P(>|z|)
#   PSY ~                                               
#     ENC              -0.197    0.084   -2.345    0.019
#     BUI               0.869    0.147    5.932    0.000

# Group 2
# Regressions:
#                    Estimate  Std.Err  z-value  P(>|z|)
#   PSY ~                                               
#     ENC              -0.291    0.078   -3.735    0.000
#     BUI               1.039    0.154    6.753    0.000

# Group 3
# Regressions:
#                    Estimate  Std.Err  z-value  P(>|z|)
#   PSY ~                                               
#     ENC              -0.111    0.085   -1.309    0.190
#     BUI               0.951    0.145    6.541    0.000

Second, we'll estimate the constrained model:

# fit a "constrained" model where both intercepts and path coefficients are fixed to be the same in all groups
lavaan_mg_constrained <- sem(sem_multiGroup_model, 
           group = "group",
           group.equal = c("intercepts", "regressions"),
           data = sim_multiGroupData_lavaan)

# see the results
summary(lavaan_mg_constrained)
## lavaan 0.6.14 ended normally after 54 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        78
##   Number of equality constraints                    18
## 
##   Number of observations per group:                   
##     1                                              200
##     2                                              200
##     3                                              200
## 
## Model Test User Model:
##                                                       
##   Test statistic                                50.528
##   Degrees of freedom                                45
##   P-value (Chi-square)                           0.264
##   Test statistic for each group:
##     1                                           19.363
##     2                                           17.440
##     3                                           13.725
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## 
## Group 1 [1]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC =~                                              
##     v5                0.918    0.081   11.349    0.000
##     v7                0.864    0.082   10.574    0.000
##     v17               1.000                           
##   BUI =~                                              
##     v42r              1.000                           
##     v43               0.770    0.116    6.610    0.000
##   PSY =~                                              
##     v44               1.000                           
##     v45               0.581    0.096    6.082    0.000
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   PSY ~                                               
##     ENC     (.p8.)   -0.205    0.048   -4.291    0.000
##     BUI     (.p9.)    0.980    0.089   11.005    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC ~~                                              
##     BUI              -0.145    0.057   -2.529    0.011
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5      (.21.)   -0.066    0.060   -1.093    0.274
##    .v7      (.22.)   -0.076    0.058   -1.318    0.187
##    .v17     (.23.)   -0.033    0.061   -0.538    0.591
##    .v42r    (.24.)    0.105    0.071    1.482    0.138
##    .v43     (.25.)    0.122    0.061    2.000    0.046
##    .v44     (.26.)    0.147    0.068    2.176    0.030
##    .v45     (.27.)    0.094    0.055    1.714    0.086
##     ENC               0.000                           
##     BUI               0.000                           
##    .PSY               0.000                           
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5                0.284    0.046    6.165    0.000
##    .v7                0.411    0.053    7.819    0.000
##    .v17               0.247    0.049    5.019    0.000
##    .v42r              0.604    0.087    6.909    0.000
##    .v43               0.782    0.092    8.488    0.000
##    .v44               0.230    0.099    2.319    0.020
##    .v45               0.655    0.073    8.958    0.000
##     ENC               0.654    0.096    6.793    0.000
##     BUI               0.566    0.099    5.740    0.000
##    .PSY               0.115    0.109    1.058    0.290
## 
## 
## Group 2 [2]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC =~                                              
##     v5                1.015    0.077   13.246    0.000
##     v7                0.807    0.074   10.908    0.000
##     v17               1.000                           
##   BUI =~                                              
##     v42r              1.000                           
##     v43               0.738    0.094    7.868    0.000
##   PSY =~                                              
##     v44               1.000                           
##     v45               0.771    0.094    8.225    0.000
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   PSY ~                                               
##     ENC     (.p8.)   -0.205    0.048   -4.291    0.000
##     BUI     (.p9.)    0.980    0.089   11.005    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC ~~                                              
##     BUI              -0.212    0.060   -3.509    0.000
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5      (.21.)   -0.066    0.060   -1.093    0.274
##    .v7      (.22.)   -0.076    0.058   -1.318    0.187
##    .v17     (.23.)   -0.033    0.061   -0.538    0.591
##    .v42r    (.24.)    0.105    0.071    1.482    0.138
##    .v43     (.25.)    0.122    0.061    2.000    0.046
##    .v44     (.26.)    0.147    0.068    2.176    0.030
##    .v45     (.27.)    0.094    0.055    1.714    0.086
##     ENC               0.109    0.088    1.234    0.217
##     BUI              -0.191    0.096   -1.994    0.046
##    .PSY               0.060    0.082    0.728    0.467
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5                0.205    0.048    4.279    0.000
##    .v7                0.492    0.057    8.594    0.000
##    .v17               0.288    0.051    5.629    0.000
##    .v42r              0.382    0.065    5.846    0.000
##    .v43               0.539    0.064    8.412    0.000
##    .v44               0.546    0.086    6.318    0.000
##    .v45               0.631    0.075    8.456    0.000
##     ENC               0.758    0.108    6.991    0.000
##     BUI               0.565    0.092    6.169    0.000
##    .PSY              -0.025    0.075   -0.333    0.739
## 
## 
## Group 3 [3]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC =~                                              
##     v5                0.943    0.077   12.230    0.000
##     v7                0.972    0.081   12.035    0.000
##     v17               1.000                           
##   BUI =~                                              
##     v42r              1.000                           
##     v43               0.862    0.113    7.599    0.000
##   PSY =~                                              
##     v44               1.000                           
##     v45               0.601    0.090    6.688    0.000
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   PSY ~                                               
##     ENC     (.p8.)   -0.205    0.048   -4.291    0.000
##     BUI     (.p9.)    0.980    0.089   11.005    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC ~~                                              
##     BUI              -0.129    0.056   -2.316    0.021
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5      (.21.)   -0.066    0.060   -1.093    0.274
##    .v7      (.22.)   -0.076    0.058   -1.318    0.187
##    .v17     (.23.)   -0.033    0.061   -0.538    0.591
##    .v42r    (.24.)    0.105    0.071    1.482    0.138
##    .v43     (.25.)    0.122    0.061    2.000    0.046
##    .v44     (.26.)    0.147    0.068    2.176    0.030
##    .v45     (.27.)    0.094    0.055    1.714    0.086
##     ENC               0.108    0.085    1.266    0.205
##     BUI              -0.207    0.095   -2.177    0.030
##    .PSY              -0.046    0.085   -0.537    0.591
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5                0.325    0.047    6.925    0.000
##    .v7                0.380    0.052    7.250    0.000
##    .v17               0.209    0.043    4.855    0.000
##    .v42r              0.521    0.079    6.623    0.000
##    .v43               0.679    0.086    7.918    0.000
##    .v44               0.158    0.103    1.544    0.122
##    .v45               0.688    0.078    8.826    0.000
##     ENC               0.658    0.092    7.175    0.000
##     BUI               0.558    0.096    5.816    0.000
##    .PSY               0.234    0.115    2.033    0.042

Third, we'll compare the free and constrained models:

anova(lavaan_mg_free,lavaan_mg_constrained)
## 
## Chi-Squared Difference Test
## 
##                       Df   AIC   BIC  Chisq Chisq diff   RMSEA Df diff
## lavaan_mg_free        33 10519 10836 33.939                           
## lavaan_mg_constrained 45 10512 10775 50.528      16.59 0.04373      12
##                       Pr(>Chisq)
## lavaan_mg_free                  
## lavaan_mg_constrained     0.1657

As the two models are not significantly different, it indicates that the regression paths do not vary by the three groups (this data could be analysed as pooled).

What if we modify the third group's population model a little bit (so that it differs from the group 1 and 2 models) and create a new version of the simulated data?

# earlier we created a simulated mg data ("sim_multiGroupData_lavaan") with three groups (each n = 200)

# we'll do it again:
# define a different population model for the third group data simulation
sem_model_simulation_group3 <- '

# Factors
ENC =~ 0.81*v5   + 0.77*v7 + 0.87*v17   
BUI =~ 0.67*v42r + 0.57*v43
PSY =~ 0.90*v44  + 0.55*v45

# Regressions
PSY ~ .70*ENC + 0.85*BUI              

# Covariances
ENC ~~ -.30*BUI                         
'

# create simulated multi-group data for the group 3
set.seed(2023)
sim_multiGroupData_lavaan_group3 <- lavaan::simulateData(sem_model_simulation_group3, 
                         sample.nobs=200, 
                         standardized = T,
                         return.type = "data.frame")

# add "group" var into df with fixed value of "3"
sim_multiGroupData_lavaan_group3$group <- 3

# create simulated multi-group data for the groups 2&3
set.seed(2023)
sim_multiGroupData_lavaan_groups2_3 <- lavaan::simulateData(sem_model_simulation, 
                         sample.nobs=c(200,200), # add "group" variable
                         standardized = T,
                         return.type = "data.frame")

# put the two data frames together
sim_multiGroupData_lavaan_v2 <- rbind(sim_multiGroupData_lavaan_groups2_3,sim_multiGroupData_lavaan_group3)

Now that we have a new simulated multi-group data, we can repeat the model fitting/comparison procedure.

First, fit the free model:

# define SEM model
sem_multiGroup_model <- '
# Factors
ENC =~ NA*v5 + v7 + 1*v17   # Encouraging leadership
BUI =~ 1*v42r + v43         # Build-up of work requirements
PSY =~ 1*v44 + v45          # Psychic stress of the work
# Regressions
PSY ~ ENC + BUI             # Predict PSY with ENC and BUI
# Covariances
ENC ~~ BUI                  # Let ENC and BUI correlate
'

# fit the "free" model v2 where the coefficients are allowed to vary across three groups
lavaan_mg_free_v2 <- sem(sem_multiGroup_model, 
           group = "group",
           data = sim_multiGroupData_lavaan_v2)

# see the results
summary(lavaan_mg_free_v2)
## lavaan 0.6.14 ended normally after 57 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        72
## 
##   Number of observations per group:                   
##     1                                              200
##     2                                              200
##     3                                              200
## 
## Model Test User Model:
##                                                       
##   Test statistic                                38.937
##   Degrees of freedom                                33
##   P-value (Chi-square)                           0.220
##   Test statistic for each group:
##     1                                           13.813
##     2                                           11.823
##     3                                           13.301
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## 
## Group 1 [1]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC =~                                              
##     v5                0.917    0.080   11.421    0.000
##     v7                0.859    0.081   10.592    0.000
##     v17               1.000                           
##   BUI =~                                              
##     v42r              1.000                           
##     v43               0.730    0.119    6.150    0.000
##   PSY =~                                              
##     v44               1.000                           
##     v45               0.592    0.099    5.998    0.000
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   PSY ~                                               
##     ENC              -0.197    0.084   -2.345    0.019
##     BUI               0.869    0.147    5.932    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC ~~                                              
##     BUI              -0.157    0.065   -2.409    0.016
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5               -0.130    0.064   -2.019    0.044
##    .v7               -0.055    0.067   -0.818    0.413
##    .v17              -0.001    0.067   -0.022    0.983
##    .v42r              0.074    0.077    0.957    0.339
##    .v43               0.163    0.075    2.178    0.029
##    .v44               0.153    0.069    2.210    0.027
##    .v45               0.072    0.067    1.069    0.285
##     ENC               0.000                           
##     BUI               0.000                           
##    .PSY               0.000                           
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5                0.277    0.046    6.093    0.000
##    .v7                0.412    0.052    7.871    0.000
##    .v17               0.244    0.049    4.958    0.000
##    .v42r              0.554    0.108    5.137    0.000
##    .v43               0.772    0.092    8.425    0.000
##    .v44               0.236    0.098    2.417    0.016
##    .v45               0.652    0.073    8.912    0.000
##     ENC               0.659    0.097    6.805    0.000
##     BUI               0.646    0.141    4.577    0.000
##    .PSY               0.150    0.113    1.332    0.183
## 
## 
## Group 2 [2]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC =~                                              
##     v5                1.004    0.076   13.231    0.000
##     v7                0.797    0.074   10.793    0.000
##     v17               1.000                           
##   BUI =~                                              
##     v42r              1.000                           
##     v43               0.763    0.106    7.184    0.000
##   PSY =~                                              
##     v44               1.000                           
##     v45               0.731    0.092    7.926    0.000
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   PSY ~                                               
##     ENC              -0.291    0.078   -3.735    0.000
##     BUI               1.039    0.154    6.753    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC ~~                                              
##     BUI              -0.181    0.061   -2.955    0.003
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5                0.070    0.070    0.994    0.320
##    .v7                0.049    0.070    0.707    0.480
##    .v17               0.023    0.072    0.318    0.751
##    .v42r             -0.094    0.068   -1.394    0.163
##    .v43              -0.003    0.065   -0.040    0.968
##    .v44              -0.013    0.079   -0.171    0.864
##    .v45              -0.005    0.071   -0.077    0.938
##     ENC               0.000                           
##     BUI               0.000                           
##    .PSY               0.000                           
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5                0.209    0.047    4.450    0.000
##    .v7                0.492    0.057    8.633    0.000
##    .v17               0.279    0.050    5.523    0.000
##    .v42r              0.387    0.072    5.355    0.000
##    .v43               0.544    0.065    8.371    0.000
##    .v44               0.537    0.089    6.056    0.000
##    .v45               0.635    0.074    8.601    0.000
##     ENC               0.764    0.109    7.015    0.000
##     BUI               0.528    0.103    5.130    0.000
##    .PSY              -0.042    0.087   -0.483    0.629
## 
## 
## Group 3 [3]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC =~                                              
##     v5                0.900    0.078   11.501    0.000
##     v7                0.859    0.080   10.786    0.000
##     v17               1.000                           
##   BUI =~                                              
##     v42r              1.000                           
##     v43               0.698    0.112    6.240    0.000
##   PSY =~                                              
##     v44               1.000                           
##     v45               0.645    0.093    6.922    0.000
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   PSY ~                                               
##     ENC               0.874    0.107    8.189    0.000
##     BUI               1.137    0.201    5.642    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC ~~                                              
##     BUI              -0.154    0.061   -2.534    0.011
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5               -0.074    0.067   -1.105    0.269
##    .v7               -0.030    0.067   -0.442    0.659
##    .v17              -0.174    0.065   -2.654    0.008
##    .v42r             -0.015    0.074   -0.196    0.845
##    .v43              -0.057    0.067   -0.848    0.396
##    .v44              -0.111    0.072   -1.555    0.120
##    .v45              -0.158    0.075   -2.095    0.036
##     ENC               0.000                           
##     BUI               0.000                           
##    .PSY               0.000                           
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5                0.363    0.048    7.515    0.000
##    .v7                0.430    0.053    8.150    0.000
##    .v17               0.210    0.042    4.969    0.000
##    .v42r              0.586    0.096    6.113    0.000
##    .v43               0.658    0.075    8.720    0.000
##    .v44               0.212    0.087    2.433    0.015
##    .v45               0.801    0.087    9.155    0.000
##     ENC               0.646    0.091    7.120    0.000
##     BUI               0.513    0.120    4.277    0.000
##    .PSY              -0.037    0.123   -0.303    0.762
# our interest (again) is to see if there are differences across three groups in these regressions:

# Group 1
# Regressions:
#                    Estimate  Std.Err  z-value  P(>|z|)
#   PSY ~                                               
#     ENC              -0.197    0.084   -2.345    0.019
#     BUI               0.869    0.147    5.932    0.000

# Group 2
# Regressions:
#                    Estimate  Std.Err  z-value  P(>|z|)
#   PSY ~                                               
#     ENC              -0.291    0.078   -3.735    0.000
#     BUI               1.039    0.154    6.753    0.000

# Group 3
# Regressions:
#                    Estimate  Std.Err  z-value  P(>|z|)
#   PSY ~                                               
#     ENC               0.874    0.107    8.189    0.000 # NOTE: Now we have quite different estimate here!!!
#     BUI               1.137    0.201    5.642    0.000

Second, estimate the constrained model with the new simulated data:

# fit a "constrained" model where both intercepts and path coefficients are fixed to be the same in all groups
lavaan_mg_constrained_v2 <- sem(sem_multiGroup_model, 
           group = "group",
           group.equal = c("intercepts", "regressions"),
           data = sim_multiGroupData_lavaan_v2)

# see the results
summary(lavaan_mg_constrained_v2)
## lavaan 0.6.14 ended normally after 85 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        78
##   Number of equality constraints                    18
## 
##   Number of observations per group:                   
##     1                                              200
##     2                                              200
##     3                                              200
## 
## Model Test User Model:
##                                                       
##   Test statistic                               129.197
##   Degrees of freedom                                45
##   P-value (Chi-square)                           0.000
##   Test statistic for each group:
##     1                                           43.169
##     2                                           41.240
##     3                                           44.788
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## 
## Group 1 [1]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC =~                                              
##     v5                0.927    0.083   11.239    0.000
##     v7                0.876    0.083   10.523    0.000
##     v17               1.000                           
##   BUI =~                                              
##     v42r              1.000                           
##     v43               0.733    0.149    4.931    0.000
##   PSY =~                                              
##     v44               1.000                           
##     v45               0.597    0.102    5.850    0.000
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   PSY ~                                               
##     ENC     (.p8.)    0.577    0.160    3.612    0.000
##     BUI     (.p9.)    2.833    0.467    6.060    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC ~~                                              
##     BUI              -0.229    0.046   -5.009    0.000
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5      (.21.)   -0.066    0.060   -1.103    0.270
##    .v7      (.22.)   -0.024    0.056   -0.423    0.672
##    .v17     (.23.)   -0.070    0.062   -1.117    0.264
##    .v42r    (.24.)    0.104    0.069    1.508    0.132
##    .v43     (.25.)    0.118    0.057    2.062    0.039
##    .v44     (.26.)    0.152    0.067    2.285    0.022
##    .v45     (.27.)    0.069    0.055    1.252    0.211
##     ENC               0.000                           
##     BUI               0.000                           
##    .PSY               0.000                           
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5                0.286    0.046    6.168    0.000
##    .v7                0.408    0.053    7.741    0.000
##    .v17               0.260    0.049    5.260    0.000
##    .v42r              0.955    0.099    9.600    0.000
##    .v43               0.992    0.098   10.114    0.000
##    .v44               0.248    0.098    2.532    0.011
##    .v45               0.648    0.073    8.865    0.000
##     ENC               0.639    0.095    6.701    0.000
##     BUI               0.233    0.051    4.598    0.000
##    .PSY              -0.649    0.247   -2.628    0.009
## 
## 
## Group 2 [2]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC =~                                              
##     v5                1.037    0.078   13.237    0.000
##     v7                0.817    0.076   10.769    0.000
##     v17               1.000                           
##   BUI =~                                              
##     v42r              1.000                           
##     v43               0.734    0.120    6.109    0.000
##   PSY =~                                              
##     v44               1.000                           
##     v45               0.709    0.090    7.857    0.000
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   PSY ~                                               
##     ENC     (.p8.)    0.577    0.160    3.612    0.000
##     BUI     (.p9.)    2.833    0.467    6.060    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC ~~                                              
##     BUI              -0.301    0.056   -5.406    0.000
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5      (.21.)   -0.066    0.060   -1.103    0.270
##    .v7      (.22.)   -0.024    0.056   -0.423    0.672
##    .v17     (.23.)   -0.070    0.062   -1.117    0.264
##    .v42r    (.24.)    0.104    0.069    1.508    0.132
##    .v43     (.25.)    0.118    0.057    2.062    0.039
##    .v44     (.26.)    0.152    0.067    2.285    0.022
##    .v45     (.27.)    0.069    0.055    1.252    0.211
##     ENC               0.112    0.087    1.293    0.196
##     BUI              -0.187    0.090   -2.086    0.037
##    .PSY               0.317    0.213    1.485    0.137
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5                0.206    0.047    4.368    0.000
##    .v7                0.492    0.057    8.611    0.000
##    .v17               0.292    0.049    5.909    0.000
##    .v42r              0.695    0.074    9.437    0.000
##    .v43               0.701    0.070   10.009    0.000
##    .v44               0.529    0.091    5.821    0.000
##    .v45               0.641    0.074    8.656    0.000
##     ENC               0.723    0.104    6.925    0.000
##     BUI               0.271    0.060    4.478    0.000
##    .PSY              -0.719    0.215   -3.339    0.001
## 
## 
## Group 3 [3]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC =~                                              
##     v5                0.857    0.076   11.242    0.000
##     v7                0.830    0.077   10.747    0.000
##     v17               1.000                           
##   BUI =~                                              
##     v42r              1.000                           
##     v43               0.735    0.155    4.733    0.000
##   PSY =~                                              
##     v44               1.000                           
##     v45               0.683    0.088    7.729    0.000
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   PSY ~                                               
##     ENC     (.p8.)    0.577    0.160    3.612    0.000
##     BUI     (.p9.)    2.833    0.467    6.060    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC ~~                                              
##     BUI               0.020    0.050    0.409    0.683
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5      (.21.)   -0.066    0.060   -1.103    0.270
##    .v7      (.22.)   -0.024    0.056   -0.423    0.672
##    .v17     (.23.)   -0.070    0.062   -1.117    0.264
##    .v42r    (.24.)    0.104    0.069    1.508    0.132
##    .v43     (.25.)    0.118    0.057    2.062    0.039
##    .v44     (.26.)    0.152    0.067    2.285    0.022
##    .v45     (.27.)    0.069    0.055    1.252    0.211
##     ENC              -0.064    0.089   -0.726    0.468
##     BUI              -0.162    0.090   -1.811    0.070
##    .PSY               0.225    0.227    0.994    0.320
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5                0.378    0.050    7.624    0.000
##    .v7                0.429    0.053    8.093    0.000
##    .v17               0.196    0.045    4.335    0.000
##    .v42r              0.884    0.092    9.564    0.000
##    .v43               0.841    0.083   10.182    0.000
##    .v44               0.232    0.082    2.833    0.005
##    .v45               0.795    0.088    9.080    0.000
##     ENC               0.689    0.095    7.225    0.000
##     BUI               0.156    0.037    4.171    0.000
##    .PSY              -0.727    0.250   -2.909    0.004

Third, compare the free and constrained models:

anova(lavaan_mg_free_v2,lavaan_mg_constrained_v2)
## 
## Chi-Squared Difference Test
## 
##                          Df   AIC   BIC   Chisq Chisq diff   RMSEA Df diff
## lavaan_mg_free_v2        33 10527 10844  38.937                           
## lavaan_mg_constrained_v2 45 10593 10857 129.197     90.261 0.18058      12
##                          Pr(>Chisq)    
## lavaan_mg_free_v2                      
## lavaan_mg_constrained_v2  4.396e-14 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Not surprisingly, now we have a stat sig difference between the two models, indicating that at least some of the paths are different across the three groups.

Next step in the process is to use constraints to identify if the ENC -> PSY and/or BUI -> PSY paths are different among groups.

lavaan_mg_model1 <- '
# Factors
ENC =~ NA*v5 + v7 + 1*v17   # Encouraging leadership
BUI =~ 1*v42r + v43         # Build-up of work requirements
PSY =~ 1*v44 + v45          # Psychic stress of the work
# Regressions
PSY ~ c("b1","b1","b1")*ENC + BUI             # Constrain in all three groups
# Covariances
ENC ~~ BUI                  # Let ENC and BUI correlate
'

# fit the single constrained model
lavaan_mg_const1_v2 <- sem(lavaan_mg_model1, 
           group = "group",
           data = sim_multiGroupData_lavaan_v2)

summary(lavaan_mg_const1_v2)
## lavaan 0.6.14 ended normally after 90 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        72
##   Number of equality constraints                     2
## 
##   Number of observations per group:                   
##     1                                              200
##     2                                              200
##     3                                              200
## 
## Model Test User Model:
##                                                       
##   Test statistic                                93.405
##   Degrees of freedom                                35
##   P-value (Chi-square)                           0.000
##   Test statistic for each group:
##     1                                           37.737
##     2                                           41.391
##     3                                           14.278
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## 
## Group 1 [1]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC =~                                              
##     v5                0.923    0.081   11.398    0.000
##     v7                0.868    0.082   10.591    0.000
##     v17               1.000                           
##   BUI =~                                              
##     v42r              1.000                           
##     v43               0.705    0.153    4.605    0.000
##   PSY =~                                              
##     v44               1.000                           
##     v45               0.597    0.103    5.810    0.000
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   PSY ~                                               
##     ENC       (b1)    0.772    0.093    8.273    0.000
##     BUI               3.324    0.732    4.543    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC ~~                                              
##     BUI              -0.236    0.061   -3.862    0.000
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5               -0.130    0.064   -2.019    0.044
##    .v7               -0.055    0.067   -0.818    0.413
##    .v17              -0.001    0.067   -0.022    0.982
##    .v42r              0.074    0.077    0.957    0.339
##    .v43               0.163    0.075    2.178    0.029
##    .v44               0.153    0.068    2.237    0.025
##    .v45               0.072    0.067    1.076    0.282
##     ENC               0.000                           
##     BUI               0.000                           
##    .PSY               0.000                           
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5                0.281    0.045    6.173    0.000
##    .v7                0.410    0.052    7.837    0.000
##    .v17               0.247    0.048    5.094    0.000
##    .v42r              0.986    0.102    9.667    0.000
##    .v43               1.009    0.100   10.076    0.000
##    .v44               0.246    0.098    2.509    0.012
##    .v45               0.649    0.073    8.864    0.000
##     ENC               0.647    0.095    6.778    0.000
##     BUI               0.214    0.073    2.924    0.003
##    .PSY              -0.854    0.334   -2.559    0.010
## 
## 
## Group 2 [2]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC =~                                              
##     v5                1.014    0.077   13.212    0.000
##     v7                0.807    0.075   10.768    0.000
##     v17               1.000                           
##   BUI =~                                              
##     v42r              1.000                           
##     v43               0.769    0.146    5.272    0.000
##   PSY =~                                              
##     v44               1.000                           
##     v45               0.712    0.094    7.571    0.000
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   PSY ~                                               
##     ENC       (b1)    0.772    0.093    8.273    0.000
##     BUI               3.946    0.733    5.381    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC ~~                                              
##     BUI              -0.257    0.058   -4.428    0.000
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5                0.070    0.070    0.994    0.320
##    .v7                0.049    0.070    0.707    0.480
##    .v17               0.023    0.072    0.319    0.749
##    .v42r             -0.094    0.068   -1.394    0.163
##    .v43              -0.003    0.065   -0.040    0.968
##    .v44              -0.013    0.078   -0.173    0.863
##    .v45              -0.005    0.070   -0.078    0.938
##     ENC               0.000                           
##     BUI               0.000                           
##    .PSY               0.000                           
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5                0.210    0.047    4.497    0.000
##    .v7                0.491    0.057    8.614    0.000
##    .v17               0.283    0.050    5.690    0.000
##    .v42r              0.729    0.074    9.853    0.000
##    .v43               0.741    0.073   10.131    0.000
##    .v44               0.529    0.091    5.842    0.000
##    .v45               0.639    0.074    8.636    0.000
##     ENC               0.748    0.107    6.975    0.000
##     BUI               0.186    0.057    3.282    0.001
##    .PSY              -1.097    0.306   -3.587    0.000
## 
## 
## Group 3 [3]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC =~                                              
##     v5                0.877    0.076   11.465    0.000
##     v7                0.840    0.078   10.818    0.000
##     v17               1.000                           
##   BUI =~                                              
##     v42r              1.000                           
##     v43               0.684    0.111    6.165    0.000
##   PSY =~                                              
##     v44               1.000                           
##     v45               0.654    0.095    6.876    0.000
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   PSY ~                                               
##     ENC       (b1)    0.772    0.093    8.273    0.000
##     BUI               1.050    0.180    5.849    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ENC ~~                                              
##     BUI              -0.130    0.062   -2.098    0.036
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5               -0.074    0.067   -1.105    0.269
##    .v7               -0.030    0.067   -0.442    0.659
##    .v17              -0.174    0.066   -2.630    0.009
##    .v42r             -0.015    0.074   -0.196    0.845
##    .v43              -0.057    0.067   -0.848    0.396
##    .v44              -0.111    0.071   -1.568    0.117
##    .v45              -0.158    0.075   -2.095    0.036
##     ENC               0.000                           
##     BUI               0.000                           
##    .PSY               0.000                           
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .v5                0.368    0.049    7.570    0.000
##    .v7                0.430    0.053    8.153    0.000
##    .v17               0.197    0.043    4.545    0.000
##    .v42r              0.560    0.097    5.769    0.000
##    .v43               0.656    0.075    8.705    0.000
##    .v44               0.214    0.087    2.474    0.013
##    .v45               0.800    0.088    9.125    0.000
##     ENC               0.674    0.093    7.232    0.000
##     BUI               0.539    0.123    4.371    0.000
##    .PSY               0.007    0.115    0.058    0.953

Compare the first constrained model (ENC -> PSY) to the free model:

anova(lavaan_mg_free_v2,lavaan_mg_const1_v2)
## 
## Chi-Squared Difference Test
## 
##                     Df   AIC   BIC  Chisq Chisq diff   RMSEA Df diff Pr(>Chisq)
## lavaan_mg_free_v2   33 10527 10844 38.937                                      
## lavaan_mg_const1_v2 35 10578 10885 93.406     54.469 0.36218       2  1.487e-12
##                        
## lavaan_mg_free_v2      
## lavaan_mg_const1_v2 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Comparison shows that there is a stat sig difference between the models, indicating that the path ENC -> PSY should not be constrained (but let vary among the groups).

Next, we investigate in a similar manner the second path (BUI -> PSY):

lavaan_mg_model2 <- '
# Factors
ENC =~ NA*v5 + v7 + 1*v17   # Encouraging leadership
BUI =~ 1*v42r + v43         # Build-up of work requirements
PSY =~ 1*v44 + v45          # Psychic stress of the work
# Regressions
PSY ~ ENC + c("b2","b2","b2")*BUI             # Constrain in all three groups
# Covariances
ENC ~~ BUI                  # Let ENC and BUI correlate
'

# fit the single constrained model
lavaan_mg_const2_v2 <- sem(lavaan_mg_model2, 
           group = "group",
           data = sim_multiGroupData_lavaan_v2)
anova(lavaan_mg_free_v2,lavaan_mg_const2_v2)
## 
## Chi-Squared Difference Test
## 
##                     Df   AIC   BIC  Chisq Chisq diff RMSEA Df diff Pr(>Chisq)
## lavaan_mg_free_v2   33 10527 10844 38.937                                    
## lavaan_mg_const2_v2 35 10524 10832 40.192     1.2552     0       2     0.5339

Model comparison shows that the models are not stat sig different. This indicates that the path BUI -> PSY should be constrained (i.e., not allowed to vary among three groups).

This last model is the most promising, if the fit measures are comparable to the free model:

library(stargazer)

lavaan_mg_free_v2.fits <- as.numeric(fitMeasures(lavaan_mg_free_v2, c("chisq",           # sem.fits.table1[1]
                                                           "df",               # sem.fits.table1[2]
                                                           "pvalue",           # sem.fits.table1[3] 
                                                           "rmsea",            # sem.fits.table1[4]
                                                           "rmsea.ci.lower",   # sem.fits.table1[5]
                                                           "rmsea.ci.upper",   # sem.fits.table1[6]
                                                           "srmr",             # sem.fits.table1[7]
                                                           "cfi"               # sem.fits.table1[8] 
                                                           )))

fit.names <- c("chisq", "df", "pvalue", "rmsea", "rmsea.ci.lower", "rmsea.ci.upper", "srmr", "cfi")  

df.fits <- data.frame(fit.names,lavaan_mg_free_v2.fits)
names(df.fits)[1] <- "Measure"
names(df.fits)[2] <- "Free"

lavaan_mg_const2_v2.fits <- as.numeric(fitMeasures(lavaan_mg_const2_v2, c("chisq",           # sem.fits.table1[1]
                                                           "df",               # sem.fits.table1[2]
                                                           "pvalue",           # sem.fits.table1[3] 
                                                           "rmsea",            # sem.fits.table1[4]
                                                           "rmsea.ci.lower",   # sem.fits.table1[5]
                                                           "rmsea.ci.upper",   # sem.fits.table1[6]
                                                           "srmr",             # sem.fits.table1[7]
                                                           "cfi"               # sem.fits.table1[8] 
                                                           )))

# fit.names <- c("chisq", "df", "pvalue", "rmsea", "rmsea.ci.lower", "rmsea.ci.upper", "srmr", "cfi")  

df.fits2 <- data.frame(fit.names,lavaan_mg_const2_v2.fits)
names(df.fits2)[2] <- "Const2"

joint.fits <- cbind(df.fits,df.fits2[2]) 
stargazer(joint.fits, summary=FALSE, type='text', rownames=FALSE, initial.zero=FALSE, digits=3, title='Comparison of fit indices')
## 
## Comparison of fit indices
## ============================
## Measure         Free  Const2
## ----------------------------
## chisq          38.937 40.192
## df               33     35  
## pvalue          .220   .251 
## rmsea           .030   .027 
## rmsea.ci.lower   0      0   
## rmsea.ci.upper  .062   .060 
## srmr            .035   .036 
## cfi             .996   .996 
## ----------------------------

Yes they are!

Now we may investigate if the three groups differ stat sig by their ENC -> PSY path coefficients.

lavaan_mg_model3 <- '
# Factors
ENC =~ NA*v5 + v7 + 1*v17   # Encouraging leadership
BUI =~ 1*v42r + v43         # Build-up of work requirements
PSY =~ 1*v44 + v45          # Psychic stress of the work
# Regressions
PSY ~ c("g1","g2","g3")*ENC + c("b2","b2","b2")*BUI  # Set labels to compare three groups ENC -> PSY and constrain BUI -> PSY
# Covariances
ENC ~~ BUI                  # Let ENC and BUI correlate

# compare ENC -> PSY coefficients btw three groups
diffENCg1g2 := g1-g2
diffENCg1g3 := g1-g3
diffENCg2g3 := g2-g3
'

lavaan_mg_const2_v2_compare <- sem(lavaan_mg_model3, 
           group = "group",
           data = sim_multiGroupData_lavaan_v2)

summary(lavaan_mg_const2_v2_compare, standardized = TRUE, fit.measures = TRUE)
## lavaan 0.6.14 ended normally after 47 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        72
##   Number of equality constraints                     2
## 
##   Number of observations per group:                   
##     1                                              200
##     2                                              200
##     3                                              200
## 
## Model Test User Model:
##                                                       
##   Test statistic                                40.192
##   Degrees of freedom                                35
##   P-value (Chi-square)                           0.251
##   Test statistic for each group:
##     1                                           14.599
##     2                                           11.852
##     3                                           13.741
## 
## Model Test Baseline Model:
## 
##   Test statistic                              1474.486
##   Degrees of freedom                                63
##   P-value                                        0.000
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    0.996
##   Tucker-Lewis Index (TLI)                       0.993
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)              -5192.158
##   Loglikelihood unrestricted model (H1)      -5172.063
##                                                       
##   Akaike (AIC)                               10524.317
##   Bayesian (BIC)                             10832.102
##   Sample-size adjusted Bayesian (SABIC)      10609.871
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.027
##   90 Percent confidence interval - lower         0.000
##   90 Percent confidence interval - upper         0.060
##   P-value H_0: RMSEA <= 0.050                    0.854
##   P-value H_0: RMSEA >= 0.080                    0.002
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.036
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## 
## Group 1 [1]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC =~                                                                
##     v5                0.917    0.080   11.417    0.000    0.744    0.816
##     v7                0.858    0.081   10.589    0.000    0.697    0.735
##     v17               1.000                               0.812    0.855
##   BUI =~                                                                
##     v42r              1.000                               0.743    0.687
##     v43               0.778    0.118    6.579    0.000    0.578    0.547
##   PSY =~                                                                
##     v44               1.000                               0.856    0.869
##     v45               0.588    0.096    6.098    0.000    0.503    0.529
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   PSY ~                                                                 
##     ENC       (g1)   -0.162    0.085   -1.910    0.056   -0.154   -0.154
##     BUI       (b2)    1.012    0.095   10.631    0.000    0.879    0.879
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC ~~                                                                
##     BUI              -0.157    0.063   -2.494    0.013   -0.260   -0.260
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5               -0.130    0.064   -2.019    0.044   -0.130   -0.143
##    .v7               -0.055    0.067   -0.818    0.413   -0.055   -0.058
##    .v17              -0.001    0.067   -0.022    0.983   -0.001   -0.002
##    .v42r              0.074    0.076    0.969    0.332    0.074    0.069
##    .v43               0.163    0.075    2.178    0.029    0.163    0.154
##    .v44               0.153    0.070    2.191    0.028    0.153    0.155
##    .v45               0.072    0.067    1.068    0.285    0.072    0.076
##     ENC               0.000                               0.000    0.000
##     BUI               0.000                               0.000    0.000
##    .PSY               0.000                               0.000    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5                0.277    0.046    6.091    0.000    0.277    0.334
##    .v7                0.412    0.052    7.873    0.000    0.412    0.459
##    .v17               0.243    0.049    4.943    0.000    0.243    0.269
##    .v42r              0.617    0.087    7.058    0.000    0.617    0.528
##    .v43               0.782    0.092    8.514    0.000    0.782    0.701
##    .v44               0.237    0.098    2.428    0.015    0.237    0.245
##    .v45               0.652    0.073    8.933    0.000    0.652    0.720
##     ENC               0.659    0.097    6.807    0.000    1.000    1.000
##     BUI               0.552    0.098    5.628    0.000    1.000    1.000
##    .PSY               0.098    0.108    0.907    0.365    0.134    0.134
## 
## 
## Group 2 [2]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC =~                                                                
##     v5                1.004    0.076   13.235    0.000    0.877    0.887
##     v7                0.797    0.074   10.793    0.000    0.697    0.705
##     v17               1.000                               0.874    0.856
##   BUI =~                                                                
##     v42r              1.000                               0.735    0.767
##     v43               0.755    0.099    7.599    0.000    0.555    0.601
##   PSY =~                                                                
##     v44               1.000                               0.833    0.751
##     v45               0.735    0.091    8.094    0.000    0.613    0.610
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   PSY ~                                                                 
##     ENC       (g2)   -0.297    0.074   -3.993    0.000   -0.311   -0.311
##     BUI       (b2)    1.012    0.095   10.631    0.000    0.893    0.893
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC ~~                                                                
##     BUI              -0.181    0.062   -2.939    0.003   -0.281   -0.281
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5                0.070    0.070    0.994    0.320    0.070    0.070
##    .v7                0.049    0.070    0.707    0.480    0.049    0.050
##    .v17               0.023    0.072    0.318    0.751    0.023    0.022
##    .v42r             -0.094    0.068   -1.391    0.164   -0.094   -0.098
##    .v43              -0.003    0.065   -0.040    0.968   -0.003   -0.003
##    .v44              -0.013    0.079   -0.171    0.864   -0.013   -0.012
##    .v45              -0.005    0.071   -0.077    0.938   -0.005   -0.005
##     ENC               0.000                               0.000    0.000
##     BUI               0.000                               0.000    0.000
##    .PSY               0.000                               0.000    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5                0.210    0.047    4.455    0.000    0.210    0.214
##    .v7                0.492    0.057    8.633    0.000    0.492    0.503
##    .v17               0.279    0.050    5.525    0.000    0.279    0.267
##    .v42r              0.379    0.065    5.878    0.000    0.379    0.412
##    .v43               0.543    0.065    8.377    0.000    0.543    0.639
##    .v44               0.538    0.088    6.097    0.000    0.538    0.436
##    .v45               0.634    0.074    8.590    0.000    0.634    0.628
##     ENC               0.764    0.109    7.015    0.000    1.000    1.000
##     BUI               0.540    0.089    6.040    0.000    1.000    1.000
##    .PSY              -0.035    0.079   -0.443    0.658   -0.050   -0.050
## 
## 
## Group 3 [3]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC =~                                                                
##     v5                0.898    0.078   11.471    0.000    0.723    0.767
##     v7                0.859    0.080   10.797    0.000    0.691    0.726
##     v17               1.000                               0.805    0.870
##   BUI =~                                                                
##     v42r              1.000                               0.759    0.717
##     v43               0.668    0.101    6.616    0.000    0.507    0.532
##   PSY =~                                                                
##     v44               1.000                               0.897    0.890
##     v45               0.649    0.094    6.912    0.000    0.582    0.545
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   PSY ~                                                                 
##     ENC       (g3)    0.840    0.092    9.106    0.000    0.754    0.754
##     BUI       (b2)    1.012    0.095   10.631    0.000    0.857    0.857
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   ENC ~~                                                                
##     BUI              -0.151    0.062   -2.418    0.016   -0.247   -0.247
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5               -0.074    0.067   -1.105    0.269   -0.074   -0.078
##    .v7               -0.030    0.067   -0.442    0.659   -0.030   -0.031
##    .v17              -0.174    0.065   -2.654    0.008   -0.174   -0.188
##    .v42r             -0.015    0.075   -0.194    0.846   -0.015   -0.014
##    .v43              -0.057    0.067   -0.848    0.396   -0.057   -0.060
##    .v44              -0.111    0.071   -1.562    0.118   -0.111   -0.110
##    .v45              -0.158    0.075   -2.095    0.036   -0.158   -0.148
##     ENC               0.000                               0.000    0.000
##     BUI               0.000                               0.000    0.000
##    .PSY               0.000                               0.000    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .v5                0.364    0.048    7.530    0.000    0.364    0.411
##    .v7                0.428    0.053    8.134    0.000    0.428    0.473
##    .v17               0.208    0.042    4.919    0.000    0.208    0.243
##    .v42r              0.544    0.082    6.609    0.000    0.544    0.486
##    .v43               0.652    0.074    8.767    0.000    0.652    0.718
##    .v44               0.212    0.087    2.440    0.015    0.212    0.209
##    .v45               0.801    0.088    9.144    0.000    0.801    0.703
##     ENC               0.648    0.091    7.128    0.000    1.000    1.000
##     BUI               0.576    0.099    5.822    0.000    1.000    1.000
##    .PSY               0.014    0.100    0.137    0.891    0.017    0.017
## 
## Defined Parameters:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##     diffENCg1g2       0.135    0.110    1.225    0.221    0.157    0.157
##     diffENCg1g3      -1.002    0.122   -8.240    0.000   -0.908   -0.908
##     diffENCg2g3      -1.136    0.115   -9.874    0.000   -1.065   -1.065
# the last part of the summary shows that the third group differs from two other groups
# 
# Defined Parameters:
#                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
#     diffENCg1g2       0.135    0.110    1.225    0.221    0.157    0.157
#     diffENCg1g3      -1.002    0.122   -8.240    0.000   -0.908   -0.908
#     diffENCg2g3      -1.136    0.115   -9.874    0.000   -1.065   -1.065

References

Beaujean, A. A. (2014). Latent Variable Modeling Using R. A Step-by-Step Guide. Routledge.

Ferrer, E., Bolker, S. M., & Grimm, K. J. (2019). Longitudinal Multivariate Psychology. Routledge.