7.4 In-Class Exercises


7.4.1 Measurement Invariance


We’ll now pick up where we left off with the At-Home Exercises by testing measurement invariance in the two-group CFA from 7.3.2.4.

As you saw in the lecture, measurement invariance testing allows us to empirically test for differences in the measurement model between the groups. If we can establish measurement invariance, we can draw the following (equivalent) conclusions:

  • Our latent constructs are defined equivalently in all groups.
  • The participants in every group are interpreting our items in the same way.
  • Participants in different groups who have the same values for the observed indicators will also have the same score on the latent variable.
  • Between-group differences in latent parameters are due to true differences in the underlying latent constructs and not caused by differences in measurement.

Anytime we make between-group comparisons (e.g., ANOVA, t-tests, moderation by group, etc.) we assume invariant measurement. That is, we assume that the scores we’re comparing have the same meaning in each group. When doing multiple group SEM, however, we’re apprised of the incredibly powerful capability of actually testing this—very important, and often violated—assumption.

The process of testing measurement invariance can get quite complex, but the basic procedure boils down to using model comparison tests to evaluate the plausibility of increasingly strong between-group constraints. For most problems, these constraints amount to the following three levels:

  1. Configural: The same pattern of free and fixed effects in all groups
  2. Weak (aka Metric): Configural + Equal factor loadings in all groups
  3. Strong (aka Scalar): Weak + Equal item intercepts in all groups

You can read more about measurement invariance here and here, and you can find a brief discussion of how to conduct measurement invariance tests in lavaan here.


7.4.1.1

Load the PGDdata2.txt data as you did for the At-Home Exercises.

  • Note: Unless otherwise specified, all analyses in Section 7.4.1 use these data.
Click to show code
library(dplyr)

## Load the data:
pgd <- read.table("PGDdata2.txt",
                  na.strings = "-999",
                  header = TRUE,
                  sep = "\t") %>%
       filter(!is.na(Kin2))

## Check the results:
head(pgd)
summary(pdg)
str(pgd)
##       Kin2            b1pss1          b2pss2           b3pss3      
##  Min.   :0.0000   Min.   :0.000   Min.   :0.0000   Min.   :0.0000  
##  1st Qu.:0.0000   1st Qu.:0.000   1st Qu.:0.0000   1st Qu.:0.0000  
##  Median :1.0000   Median :1.000   Median :0.0000   Median :1.0000  
##  Mean   :0.6661   Mean   :1.236   Mean   :0.4622   Mean   :0.9771  
##  3rd Qu.:1.0000   3rd Qu.:2.000   3rd Qu.:1.0000   3rd Qu.:1.0000  
##  Max.   :1.0000   Max.   :5.000   Max.   :3.0000   Max.   :5.0000  
##                                                    NA's   :1       
##      b4pss4          b5pss5      
##  Min.   :0.000   Min.   :0.0000  
##  1st Qu.:0.000   1st Qu.:0.0000  
##  Median :1.000   Median :0.0000  
##  Mean   :1.009   Mean   :0.6761  
##  3rd Qu.:2.000   3rd Qu.:1.0000  
##  Max.   :3.000   Max.   :3.0000  
##                  NA's   :1
## 'data.frame':    569 obs. of  6 variables:
##  $ Kin2  : int  0 0 1 1 0 1 1 1 1 1 ...
##  $ b1pss1: int  1 1 1 1 1 2 1 3 1 1 ...
##  $ b2pss2: int  1 0 1 0 1 2 1 2 0 0 ...
##  $ b3pss3: int  1 0 1 1 2 2 1 2 1 1 ...
##  $ b4pss4: int  1 1 1 1 0 2 2 3 0 1 ...
##  $ b5pss5: int  1 0 0 0 0 1 2 3 0 0 ...

7.4.1.2

Test configural, weak, and strong invariance using the multiple-group CFA from 7.3.2.4.

  • What are your conclusions?
Click to show code
library(lavaan)
library(semTools) # provides the compareFit() function

## Define the syntax for the CFA model:
cfaMod <- 'grief =~ b1pss1 + b2pss2 + b3pss3 + b4pss4 + b5pss5'

## Estimate the configural model:
configOut <- cfa(cfaMod, data = pgd, group = "Kin2")

## Estimate the weak invariance model:
weakOut <- cfa(cfaMod, data = pgd, group = "Kin2", group.equal = "loadings")

## Estimate the strong invariance model:
strongOut <- cfa(cfaMod,
                 data = pgd,
                 group = "Kin2",
                 group.equal = c("loadings", "intercepts")
                 )

summary(configOut)
## lavaan 0.6-18 ended normally after 27 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        30
## 
##   Number of observations per group:               Used       Total
##     0                                              188         190
##     1                                              379         379
## 
## Model Test User Model:
##                                                       
##   Test statistic                                11.317
##   Degrees of freedom                                10
##   P-value (Chi-square)                           0.333
##   Test statistic for each group:
##     0                                            8.976
##     1                                            2.340
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## 
## Group 1 [0]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   grief =~                                            
##     b1pss1            1.000                           
##     b2pss2            0.372    0.076    4.922    0.000
##     b3pss3            0.938    0.118    7.986    0.000
##     b4pss4            0.909    0.116    7.848    0.000
##     b5pss5            0.951    0.122    7.774    0.000
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .b1pss1            1.346    0.072   18.727    0.000
##    .b2pss2            0.441    0.046    9.499    0.000
##    .b3pss3            1.059    0.068   15.618    0.000
##    .b4pss4            1.122    0.067   16.671    0.000
##    .b5pss5            0.745    0.071   10.442    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .b1pss1            0.478    0.067    7.118    0.000
##    .b2pss2            0.338    0.037    9.205    0.000
##    .b3pss3            0.430    0.060    7.170    0.000
##    .b4pss4            0.445    0.060    7.408    0.000
##    .b5pss5            0.511    0.068    7.519    0.000
##     grief             0.493    0.098    5.007    0.000
## 
## 
## Group 2 [1]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   grief =~                                            
##     b1pss1            1.000                           
##     b2pss2            0.502    0.052    9.597    0.000
##     b3pss3            0.785    0.066   11.945    0.000
##     b4pss4            0.708    0.062   11.497    0.000
##     b5pss5            0.762    0.062   12.185    0.000
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .b1pss1            1.182    0.051   23.277    0.000
##    .b2pss2            0.475    0.037   12.973    0.000
##    .b3pss3            0.934    0.046   20.460    0.000
##    .b4pss4            0.955    0.043   22.270    0.000
##    .b5pss5            0.644    0.043   14.879    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .b1pss1            0.385    0.043    8.862    0.000
##    .b2pss2            0.359    0.029   12.468    0.000
##    .b3pss3            0.425    0.039   11.025    0.000
##    .b4pss4            0.401    0.035   11.420    0.000
##    .b5pss5            0.366    0.034   10.767    0.000
##     grief             0.592    0.073    8.081    0.000
summary(weakOut)
## lavaan 0.6-18 ended normally after 22 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        30
##   Number of equality constraints                     4
## 
##   Number of observations per group:               Used       Total
##     0                                              188         190
##     1                                              379         379
## 
## Model Test User Model:
##                                                       
##   Test statistic                                19.275
##   Degrees of freedom                                14
##   P-value (Chi-square)                           0.155
##   Test statistic for each group:
##     0                                           14.525
##     1                                            4.751
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## 
## Group 1 [0]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   grief =~                                            
##     b1pss1            1.000                           
##     b2pss2  (.p2.)    0.457    0.043   10.680    0.000
##     b3pss3  (.p3.)    0.824    0.057   14.374    0.000
##     b4pss4  (.p4.)    0.756    0.054   13.890    0.000
##     b5pss5  (.p5.)    0.805    0.056   14.388    0.000
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .b1pss1            1.346    0.073   18.353    0.000
##    .b2pss2            0.441    0.049    9.045    0.000
##    .b3pss3            1.059    0.067   15.828    0.000
##    .b4pss4            1.122    0.066   17.102    0.000
##    .b5pss5            0.745    0.070   10.688    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .b1pss1            0.434    0.064    6.779    0.000
##    .b2pss2            0.327    0.037    8.898    0.000
##    .b3pss3            0.449    0.058    7.786    0.000
##    .b4pss4            0.480    0.058    8.209    0.000
##    .b5pss5            0.539    0.066    8.207    0.000
##     grief             0.577    0.086    6.691    0.000
## 
## 
## Group 2 [1]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   grief =~                                            
##     b1pss1            1.000                           
##     b2pss2  (.p2.)    0.457    0.043   10.680    0.000
##     b3pss3  (.p3.)    0.824    0.057   14.374    0.000
##     b4pss4  (.p4.)    0.756    0.054   13.890    0.000
##     b5pss5  (.p5.)    0.805    0.056   14.388    0.000
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .b1pss1            1.182    0.050   23.496    0.000
##    .b2pss2            0.475    0.036   13.281    0.000
##    .b3pss3            0.934    0.046   20.325    0.000
##    .b4pss4            0.955    0.043   21.999    0.000
##    .b5pss5            0.644    0.044   14.731    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .b1pss1            0.399    0.042    9.474    0.000
##    .b2pss2            0.367    0.029   12.831    0.000
##    .b3pss3            0.420    0.038   11.019    0.000
##    .b4pss4            0.394    0.035   11.304    0.000
##    .b5pss5            0.361    0.034   10.686    0.000
##     grief             0.561    0.065    8.564    0.000
summary(strongOut)
## lavaan 0.6-18 ended normally after 26 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        31
##   Number of equality constraints                     9
## 
##   Number of observations per group:               Used       Total
##     0                                              188         190
##     1                                              379         379
## 
## Model Test User Model:
##                                                       
##   Test statistic                                23.968
##   Degrees of freedom                                18
##   P-value (Chi-square)                           0.156
##   Test statistic for each group:
##     0                                           17.123
##     1                                            6.846
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## 
## Group 1 [0]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   grief =~                                            
##     b1pss1            1.000                           
##     b2pss2  (.p2.)    0.449    0.042   10.562    0.000
##     b3pss3  (.p3.)    0.824    0.057   14.467    0.000
##     b4pss4  (.p4.)    0.760    0.054   14.007    0.000
##     b5pss5  (.p5.)    0.803    0.056   14.457    0.000
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .b1pss1  (.12.)    1.332    0.066   20.221    0.000
##    .b2pss2  (.13.)    0.505    0.037   13.718    0.000
##    .b3pss3  (.14.)    1.055    0.057   18.601    0.000
##    .b4pss4  (.15.)    1.081    0.053   20.237    0.000
##    .b5pss5  (.16.)    0.756    0.056   13.525    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .b1pss1            0.435    0.064    6.773    0.000
##    .b2pss2            0.332    0.037    8.937    0.000
##    .b3pss3            0.448    0.058    7.776    0.000
##    .b4pss4            0.480    0.059    8.190    0.000
##    .b5pss5            0.539    0.066    8.207    0.000
##     grief             0.579    0.086    6.701    0.000
## 
## 
## Group 2 [1]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   grief =~                                            
##     b1pss1            1.000                           
##     b2pss2  (.p2.)    0.449    0.042   10.562    0.000
##     b3pss3  (.p3.)    0.824    0.057   14.467    0.000
##     b4pss4  (.p4.)    0.760    0.054   14.007    0.000
##     b5pss5  (.p5.)    0.803    0.056   14.457    0.000
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .b1pss1  (.12.)    1.332    0.066   20.221    0.000
##    .b2pss2  (.13.)    0.505    0.037   13.718    0.000
##    .b3pss3  (.14.)    1.055    0.057   18.601    0.000
##    .b4pss4  (.15.)    1.081    0.053   20.237    0.000
##    .b5pss5  (.16.)    0.756    0.056   13.525    0.000
##     grief            -0.144    0.076   -1.911    0.056
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .b1pss1            0.398    0.042    9.469    0.000
##    .b2pss2            0.370    0.029   12.872    0.000
##    .b3pss3            0.419    0.038   11.014    0.000
##    .b4pss4            0.393    0.035   11.276    0.000
##    .b5pss5            0.361    0.034   10.700    0.000
##     grief             0.561    0.065    8.586    0.000
## Test invariance through model comparison tests:
compareFit(configOut, weakOut, strongOut) %>% summary()
## ################### Nested Model Comparison #########################
## 
## Chi-Squared Difference Test
## 
##           Df    AIC    BIC  Chisq Chisq diff    RMSEA Df diff Pr(>Chisq)  
## configOut 10 6472.7 6602.9 11.317                                         
## weakOut   14 6472.7 6585.5 19.275     7.9585 0.059083       4    0.09311 .
## strongOut 18 6469.4 6564.9 23.968     4.6931 0.024722       4    0.32026  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## ####################### Model Fit Indices ###########################
##             chisq df pvalue rmsea    cfi    tli  srmr       aic       bic
## configOut 11.317† 10   .333 .022† 0.998† 0.997† .017† 6472.727  6602.937 
## weakOut   19.275  14   .155 .036   .993   .990  .038  6472.685  6585.534 
## strongOut 23.968  18   .156 .034   .992   .991  .042  6469.378† 6564.866†
## 
## ################## Differences in Fit Indices #######################
##                     df  rmsea    cfi    tli  srmr    aic     bic
## weakOut - configOut  4  0.015 -0.005 -0.006 0.021 -0.041 -17.403
## strongOut - weakOut  4 -0.002 -0.001  0.001 0.004 -3.307 -20.668
Click for explanation
  • Configural invariance holds.
    • The unrestricted, two-group model fits the data very well (\(\chi^2[10] = 11.32\), \(p = 0.333\), \(\textit{RMSEA} = 0.022\), \(\textit{CFI} = 0.998\), \(\textit{SRMR} = 0.017\)).
  • Weak invariance holds.
    • The model comparison test shows a non-significant loss of fit between the configural and weak models (\(\Delta \chi^2[4] = 7.96\), \(p = 0.093\)).
  • Strong invariance holds.
    • The model comparison test shows a non-significant loss of fit between the weak and strong models (\(\Delta \chi^2[4] = 4.69\), \(p = 0.32\)).
    • The strongly invariant model still fits the data well (\(\chi^2[18] = 23.97\), \(p = 0.156\), \(\textit{RMSEA} = 0.034\), \(\textit{CFI} = 0.992\), \(\textit{SRMR} = 0.042\)).

7.4.2 Testing Between-Group Differences


Once we establish strong invariance, we have empirical evidence that latent mean levels are comparable across groups. Hence, we can test for differences in those latent means. In this section, we’ll conduct the equivalent of a t-test using our two-group CFA model.

More specifically, we want to know if the latent mean of grief differs significantly between the Kin2 groups. The null and alternative hypotheses for this test are as follows:

\[ H_0: \alpha_1 = \alpha_2\\ H_1: \alpha_1 \neq \alpha_2 \]

Where, \(\alpha_1\) and \(\alpha_2\) represent the latent means in Group 1 and Group 2, respectively.


7.4.2.1

Use the strongly invariant model from 7.4.1.2 to test the latent mean difference described above.

  • What is your conclusion?
Click to show code
## Estimate the model with the latent means equated:
resOut <- cfa(cfaMod,
              data = pgd,
              group = "Kin2",
              group.equal = c("loadings", "intercepts", "means")
              )

## Check the results:
summary(resOut)
## lavaan 0.6-18 ended normally after 24 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        30
##   Number of equality constraints                     9
## 
##   Number of observations per group:               Used       Total
##     0                                              188         190
##     1                                              379         379
## 
## Model Test User Model:
##                                                       
##   Test statistic                                27.615
##   Degrees of freedom                                19
##   P-value (Chi-square)                           0.091
##   Test statistic for each group:
##     0                                           19.755
##     1                                            7.860
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## 
## Group 1 [0]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   grief =~                                            
##     b1pss1            1.000                           
##     b2pss2  (.p2.)    0.451    0.043   10.591    0.000
##     b3pss3  (.p3.)    0.824    0.057   14.450    0.000
##     b4pss4  (.p4.)    0.759    0.054   13.976    0.000
##     b5pss5  (.p5.)    0.804    0.056   14.448    0.000
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .b1pss1  (.12.)    1.234    0.042   29.668    0.000
##    .b2pss2  (.13.)    0.461    0.029   15.988    0.000
##    .b3pss3  (.14.)    0.974    0.038   25.664    0.000
##    .b4pss4  (.15.)    1.006    0.036   27.699    0.000
##    .b5pss5  (.16.)    0.676    0.037   18.267    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .b1pss1            0.436    0.064    6.770    0.000
##    .b2pss2            0.331    0.037    8.925    0.000
##    .b3pss3            0.448    0.058    7.767    0.000
##    .b4pss4            0.482    0.059    8.194    0.000
##    .b5pss5            0.538    0.066    8.197    0.000
##     grief             0.588    0.088    6.714    0.000
## 
## 
## Group 2 [1]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   grief =~                                            
##     b1pss1            1.000                           
##     b2pss2  (.p2.)    0.451    0.043   10.591    0.000
##     b3pss3  (.p3.)    0.824    0.057   14.450    0.000
##     b4pss4  (.p4.)    0.759    0.054   13.976    0.000
##     b5pss5  (.p5.)    0.804    0.056   14.448    0.000
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .b1pss1  (.12.)    1.234    0.042   29.668    0.000
##    .b2pss2  (.13.)    0.461    0.029   15.988    0.000
##    .b3pss3  (.14.)    0.974    0.038   25.664    0.000
##    .b4pss4  (.15.)    1.006    0.036   27.699    0.000
##    .b5pss5  (.16.)    0.676    0.037   18.267    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .b1pss1            0.399    0.042    9.469    0.000
##    .b2pss2            0.370    0.029   12.863    0.000
##    .b3pss3            0.419    0.038   11.012    0.000
##    .b4pss4            0.394    0.035   11.283    0.000
##    .b5pss5            0.361    0.034   10.691    0.000
##     grief             0.563    0.066    8.584    0.000
## Test the mean differences via a LRT:
anova(strongOut, resOut)
Click for explanation

We can equate the latent means by specifying the group.equal = "means" argument in cfa(). Then, we simply compare this constrained model to the strong invariance model to get our test of mean differences.

In this case, the means of the grief factor do not significantly differ between Kin2 groups (\(\Delta \chi^2[1] = 3.65\), \(p = 0.056\)), assuming we adopt an alpha-level of 0.05 or lower for the test.


7.4.3 Multiple-Group SEM for Moderation


Now, we’re going to revisit the TORA model from the Week 6 In-Class Exercises, and use a multiple-group model to test the moderating effect of sex.


7.4.3.1

Load the data contained in the toradata.csv file.

Click to show code
condom <- read.csv("toradata.csv", stringsAsFactors = TRUE)

Before we get to any moderation tests, however, we first need to establish measurement invariance. The first step in any multiple-group analysis that includes latent variables is measurement invariance testing.


7.4.3.2

Test for measurement invariance across sex groups in the three latent variables of the TORA model from 6.4.2.

  • Test configural, weak, and strong invariance.
  • Test for invariance in all three latent factors simultaneously.
  • Is full measurement invariance (i.e., up to and including strong invariance) supported?
Click to show code
tora_cfa <- '
  attitudes =~ attit_1   + attit_2   + attit_3
  norms     =~ norm_1    + norm_2    + norm_3
  control   =~ control_1 + control_2 + control_3
'

## Estimate the models:
config <- cfa(tora_cfa, data = condom, group = "sex")
weak <- cfa(tora_cfa, data = condom, group = "sex", group.equal = "loadings")
strong <- cfa(tora_cfa, 
              data = condom, 
              group = "sex",
              group.equal = c("loadings", "intercepts")
              )

## Check that everything went well:
summary(config)
## lavaan 0.6-18 ended normally after 54 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        60
## 
##   Number of observations per group:                   
##     woman                                          161
##     man                                             89
## 
## Model Test User Model:
##                                                       
##   Test statistic                                66.565
##   Degrees of freedom                                48
##   P-value (Chi-square)                           0.039
##   Test statistic for each group:
##     woman                                       42.623
##     man                                         23.941
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## 
## Group 1 [woman]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   attitudes =~                                        
##     attit_1           1.000                           
##     attit_2           1.005    0.075   13.427    0.000
##     attit_3          -0.965    0.075  -12.878    0.000
##   norms =~                                            
##     norm_1            1.000                           
##     norm_2            0.952    0.101    9.470    0.000
##     norm_3            0.879    0.101    8.742    0.000
##   control =~                                          
##     control_1         1.000                           
##     control_2         0.794    0.144    5.526    0.000
##     control_3         0.989    0.152    6.523    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   attitudes ~~                                        
##     norms             0.450    0.087    5.200    0.000
##     control           0.468    0.089    5.249    0.000
##   norms ~~                                            
##     control           0.387    0.079    4.912    0.000
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .attit_1           2.839    0.090   31.702    0.000
##    .attit_2           2.907    0.084   34.728    0.000
##    .attit_3           3.174    0.084   37.969    0.000
##    .norm_1            2.832    0.080   35.342    0.000
##    .norm_2            2.832    0.079   35.775    0.000
##    .norm_3            2.795    0.081   34.694    0.000
##    .control_1         2.851    0.082   34.755    0.000
##    .control_2         2.857    0.081   35.104    0.000
##    .control_3         2.888    0.081   35.877    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .attit_1           0.398    0.059    6.739    0.000
##    .attit_2           0.227    0.045    5.011    0.000
##    .attit_3           0.294    0.048    6.092    0.000
##    .norm_1            0.346    0.065    5.328    0.000
##    .norm_2            0.385    0.065    5.962    0.000
##    .norm_3            0.513    0.072    7.108    0.000
##    .control_1         0.587    0.090    6.531    0.000
##    .control_2         0.754    0.096    7.815    0.000
##    .control_3         0.557    0.086    6.453    0.000
##     attitudes         0.893    0.142    6.273    0.000
##     norms             0.688    0.121    5.706    0.000
##     control           0.497    0.119    4.184    0.000
## 
## 
## Group 2 [man]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   attitudes =~                                        
##     attit_1           1.000                           
##     attit_2           1.167    0.149    7.843    0.000
##     attit_3          -1.060    0.142   -7.443    0.000
##   norms =~                                            
##     norm_1            1.000                           
##     norm_2            1.070    0.215    4.965    0.000
##     norm_3            0.922    0.189    4.869    0.000
##   control =~                                          
##     control_1         1.000                           
##     control_2         0.995    0.290    3.435    0.001
##     control_3         0.949    0.285    3.332    0.001
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   attitudes ~~                                        
##     norms             0.086    0.103    0.837    0.403
##     control           0.388    0.113    3.430    0.001
##   norms ~~                                            
##     control           0.200    0.101    1.976    0.048
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .attit_1           3.270    0.117   28.063    0.000
##    .attit_2           3.180    0.128   24.905    0.000
##    .attit_3           2.787    0.126   22.187    0.000
##    .norm_1            3.236    0.131   24.692    0.000
##    .norm_2            3.337    0.132   25.293    0.000
##    .norm_3            3.303    0.131   25.136    0.000
##    .control_1         3.157    0.111   28.415    0.000
##    .control_2         3.135    0.129   24.249    0.000
##    .control_3         3.213    0.130   24.805    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .attit_1           0.440    0.095    4.631    0.000
##    .attit_2           0.405    0.109    3.699    0.000
##    .attit_3           0.541    0.112    4.822    0.000
##    .norm_1            0.740    0.175    4.230    0.000
##    .norm_2            0.647    0.182    3.555    0.000
##    .norm_3            0.868    0.175    4.972    0.000
##    .control_1         0.673    0.146    4.602    0.000
##    .control_2         1.066    0.197    5.417    0.000
##    .control_3         1.110    0.199    5.582    0.000
##     attitudes         0.768    0.182    4.220    0.000
##     norms             0.788    0.242    3.259    0.001
##     control           0.426    0.168    2.537    0.011
summary(weak)
## lavaan 0.6-18 ended normally after 37 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        60
##   Number of equality constraints                     6
## 
##   Number of observations per group:                   
##     woman                                          161
##     man                                             89
## 
## Model Test User Model:
##                                                       
##   Test statistic                                68.557
##   Degrees of freedom                                54
##   P-value (Chi-square)                           0.088
##   Test statistic for each group:
##     woman                                       43.148
##     man                                         25.409
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## 
## Group 1 [woman]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   attitudes =~                                        
##     attit_1           1.000                           
##     attit_2 (.p2.)    1.048    0.068   15.413    0.000
##     attit_3 (.p3.)   -0.995    0.067  -14.762    0.000
##   norms =~                                            
##     norm_1            1.000                           
##     norm_2  (.p5.)    0.977    0.091   10.708    0.000
##     norm_3  (.p6.)    0.889    0.089    9.996    0.000
##   control =~                                          
##     cntrl_1           1.000                           
##     cntrl_2 (.p8.)    0.843    0.130    6.506    0.000
##     cntrl_3 (.p9.)    0.983    0.135    7.306    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   attitudes ~~                                        
##     norms             0.431    0.082    5.256    0.000
##     control           0.450    0.083    5.395    0.000
##   norms ~~                                            
##     control           0.378    0.075    5.031    0.000
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .attit_1           2.839    0.088   32.194    0.000
##    .attit_2           2.907    0.084   34.445    0.000
##    .attit_3           3.174    0.084   37.913    0.000
##    .norm_1            2.832    0.080   35.504    0.000
##    .norm_2            2.832    0.080   35.571    0.000
##    .norm_3            2.795    0.080   34.727    0.000
##    .control_1         2.851    0.082   34.882    0.000
##    .control_2         2.857    0.082   34.746    0.000
##    .control_3         2.888    0.080   36.037    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .attit_1           0.408    0.058    6.987    0.000
##    .attit_2           0.221    0.045    4.896    0.000
##    .attit_3           0.293    0.048    6.128    0.000
##    .norm_1            0.353    0.063    5.580    0.000
##    .norm_2            0.380    0.064    5.952    0.000
##    .norm_3            0.512    0.071    7.178    0.000
##    .control_1         0.590    0.088    6.695    0.000
##    .control_2         0.744    0.096    7.731    0.000
##    .control_3         0.565    0.085    6.663    0.000
##     attitudes         0.844    0.129    6.540    0.000
##     norms             0.672    0.113    5.921    0.000
##     control           0.485    0.110    4.417    0.000
## 
## 
## Group 2 [man]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   attitudes =~                                        
##     attit_1           1.000                           
##     attit_2 (.p2.)    1.048    0.068   15.413    0.000
##     attit_3 (.p3.)   -0.995    0.067  -14.762    0.000
##   norms =~                                            
##     norm_1            1.000                           
##     norm_2  (.p5.)    0.977    0.091   10.708    0.000
##     norm_3  (.p6.)    0.889    0.089    9.996    0.000
##   control =~                                          
##     cntrl_1           1.000                           
##     cntrl_2 (.p8.)    0.843    0.130    6.506    0.000
##     cntrl_3 (.p9.)    0.983    0.135    7.306    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   attitudes ~~                                        
##     norms             0.092    0.114    0.807    0.420
##     control           0.425    0.109    3.912    0.000
##   norms ~~                                            
##     control           0.217    0.103    2.100    0.036
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .attit_1           3.270    0.120   27.254    0.000
##    .attit_2           3.180    0.125   25.501    0.000
##    .attit_3           2.787    0.125   22.275    0.000
##    .norm_1            3.236    0.132   24.423    0.000
##    .norm_2            3.337    0.130   25.610    0.000
##    .norm_3            3.303    0.132   25.086    0.000
##    .control_1         3.157    0.112   28.208    0.000
##    .control_2         3.135    0.127   24.750    0.000
##    .control_3         3.213    0.131   24.540    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .attit_1           0.419    0.093    4.528    0.000
##    .attit_2           0.438    0.099    4.436    0.000
##    .attit_3           0.540    0.107    5.057    0.000
##    .norm_1            0.704    0.158    4.456    0.000
##    .norm_2            0.692    0.153    4.520    0.000
##    .norm_3            0.864    0.164    5.271    0.000
##    .control_1         0.668    0.139    4.797    0.000
##    .control_2         1.110    0.186    5.960    0.000
##    .control_3         1.094    0.193    5.663    0.000
##     attitudes         0.862    0.166    5.200    0.000
##     norms             0.859    0.193    4.443    0.000
##     control           0.447    0.137    3.260    0.001
summary(strong)
## lavaan 0.6-18 ended normally after 60 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        63
##   Number of equality constraints                    15
## 
##   Number of observations per group:                   
##     woman                                          161
##     man                                             89
## 
## Model Test User Model:
##                                                       
##   Test statistic                                72.050
##   Degrees of freedom                                60
##   P-value (Chi-square)                           0.137
##   Test statistic for each group:
##     woman                                       43.961
##     man                                         28.089
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## 
## Group 1 [woman]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   attitudes =~                                        
##     attit_1           1.000                           
##     attit_2 (.p2.)    1.028    0.065   15.693    0.000
##     attit_3 (.p3.)   -0.990    0.065  -15.114    0.000
##   norms =~                                            
##     norm_1            1.000                           
##     norm_2  (.p5.)    0.998    0.089   11.182    0.000
##     norm_3  (.p6.)    0.918    0.088   10.467    0.000
##   control =~                                          
##     cntrl_1           1.000                           
##     cntrl_2 (.p8.)    0.848    0.126    6.736    0.000
##     cntrl_3 (.p9.)    0.987    0.131    7.558    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   attitudes ~~                                        
##     norms             0.428    0.081    5.259    0.000
##     control           0.454    0.084    5.438    0.000
##   norms ~~                                            
##     control           0.372    0.073    5.060    0.000
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .attit_1 (.25.)    2.864    0.085   33.535    0.000
##    .attit_2 (.26.)    2.887    0.083   34.826    0.000
##    .attit_3 (.27.)    3.166    0.082   38.500    0.000
##    .norm_1  (.28.)    2.816    0.078   36.330    0.000
##    .norm_2  (.29.)    2.838    0.078   36.453    0.000
##    .norm_3  (.30.)    2.812    0.078   36.253    0.000
##    .cntrl_1 (.31.)    2.847    0.078   36.562    0.000
##    .cntrl_2 (.32.)    2.859    0.076   37.381    0.000
##    .cntrl_3 (.33.)    2.891    0.077   37.531    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .attit_1           0.405    0.058    6.931    0.000
##    .attit_2           0.226    0.045    5.051    0.000
##    .attit_3           0.291    0.048    6.084    0.000
##    .norm_1            0.362    0.062    5.795    0.000
##    .norm_2            0.377    0.064    5.931    0.000
##    .norm_3            0.506    0.071    7.109    0.000
##    .control_1         0.592    0.088    6.743    0.000
##    .control_2         0.743    0.096    7.739    0.000
##    .control_3         0.566    0.085    6.684    0.000
##     attitudes         0.861    0.130    6.607    0.000
##     norms             0.650    0.109    5.950    0.000
##     control           0.482    0.108    4.477    0.000
## 
## 
## Group 2 [man]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   attitudes =~                                        
##     attit_1           1.000                           
##     attit_2 (.p2.)    1.028    0.065   15.693    0.000
##     attit_3 (.p3.)   -0.990    0.065  -15.114    0.000
##   norms =~                                            
##     norm_1            1.000                           
##     norm_2  (.p5.)    0.998    0.089   11.182    0.000
##     norm_3  (.p6.)    0.918    0.088   10.467    0.000
##   control =~                                          
##     cntrl_1           1.000                           
##     cntrl_2 (.p8.)    0.848    0.126    6.736    0.000
##     cntrl_3 (.p9.)    0.987    0.131    7.558    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   attitudes ~~                                        
##     norms             0.093    0.113    0.825    0.409
##     control           0.428    0.109    3.926    0.000
##   norms ~~                                            
##     control           0.213    0.101    2.102    0.036
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .attit_1 (.25.)    2.864    0.085   33.535    0.000
##    .attit_2 (.26.)    2.887    0.083   34.826    0.000
##    .attit_3 (.27.)    3.166    0.082   38.500    0.000
##    .norm_1  (.28.)    2.816    0.078   36.330    0.000
##    .norm_2  (.29.)    2.838    0.078   36.453    0.000
##    .norm_3  (.30.)    2.812    0.078   36.253    0.000
##    .cntrl_1 (.31.)    2.847    0.078   36.562    0.000
##    .cntrl_2 (.32.)    2.859    0.076   37.381    0.000
##    .cntrl_3 (.33.)    2.891    0.077   37.531    0.000
##     attitds           0.356    0.133    2.680    0.007
##     norms             0.480    0.133    3.602    0.000
##     control           0.318    0.116    2.733    0.006
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .attit_1           0.420    0.094    4.484    0.000
##    .attit_2           0.456    0.100    4.557    0.000
##    .attit_3           0.537    0.107    5.023    0.000
##    .norm_1            0.724    0.157    4.599    0.000
##    .norm_2            0.686    0.153    4.489    0.000
##    .norm_3            0.859    0.165    5.220    0.000
##    .control_1         0.669    0.139    4.821    0.000
##    .control_2         1.109    0.186    5.958    0.000
##    .control_3         1.094    0.193    5.664    0.000
##     attitudes         0.872    0.167    5.214    0.000
##     norms             0.830    0.186    4.455    0.000
##     control           0.445    0.136    3.280    0.001
## Test measurement invariance:
compareFit(config, weak, strong) %>% summary()
## ################### Nested Model Comparison #########################
## 
## Chi-Squared Difference Test
## 
##        Df    AIC    BIC  Chisq Chisq diff RMSEA Df diff Pr(>Chisq)
## config 48 6021.5 6232.8 66.565                                    
## weak   54 6011.5 6201.6 68.557     1.9924     0       6     0.9204
## strong 60 6003.0 6172.0 72.050     3.4934     0       6     0.7448
## 
## ####################### Model Fit Indices ###########################
##          chisq df pvalue rmsea   cfi   tli  srmr       aic       bic
## config 66.565† 48   .039 .056  .979  .968  .048† 6021.476  6232.764 
## weak   68.557  54   .088 .046  .983  .978  .050  6011.469  6201.628 
## strong 72.050  60   .137 .040† .986† .983† .051  6002.962† 6171.992†
## 
## ################## Differences in Fit Indices #######################
##               df  rmsea   cfi   tli  srmr     aic     bic
## weak - config  6 -0.009 0.005 0.010 0.003 -10.008 -31.136
## strong - weak  6 -0.006 0.003 0.006 0.001  -8.507 -29.635
Click for explanation

Yes, we can establish full measurement invariance.

  • Configural invariance holds.
    • The unrestricted, multiple-group model fits the data well (\(\chi^2[48] = 66.56\), \(p = 0.039\), \(\textit{RMSEA} = 0.056\), \(\textit{CFI} = 0.979\), \(\textit{SRMR} = 0.048\)).
  • Weak invariance holds.
    • The model comparison test shows a non-significant loss of fit between the configural and weak models (\(\Delta \chi^2[6] = 1.99\), \(p = 0.92\)).
  • Strong invariance holds.
    • The model comparison test shows a non-significant loss of fit between the weak and strong models (\(\Delta \chi^2[6] = 3.49\), \(p = 0.745\)).
    • The strongly invariant model still fits the data well (\(\chi^2[60] = 72.05\), \(p = 0.137\), \(\textit{RMSEA} = 0.04\), \(\textit{CFI} = 0.986\), \(\textit{SRMR} = 0.051\)).

Once we’ve established measurement invariance, we can move on to testing hypotheses about between-group differences secure in the knowledge that our latent factors represent the same hypothetical constructs in all groups.


7.4.3.3

Estimate the full TORA model from 6.4.4 as a multiple-group model.

  • Use sex as the grouping variables.
  • Keep the strong invariance constraints in place.
Click to show code
## Add the structural paths to the model:
tora_sem <- paste(tora_cfa,
                  'intent ~ attitudes + norms
                   behavior ~ intent + control',
                  sep = '\n')

## Estimate the model:
toraOut <- sem(tora_sem, 
               data = condom, 
               group = "sex", 
               group.equal = c("loadings", "intercepts")
               )

## Check the results:
summary(toraOut, fit.measures = TRUE, standardized = TRUE, rsquare = TRUE)
## lavaan 0.6-18 ended normally after 62 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        79
##   Number of equality constraints                    17
## 
##   Number of observations per group:                   
##     woman                                          161
##     man                                             89
## 
## Model Test User Model:
##                                                       
##   Test statistic                               141.903
##   Degrees of freedom                                92
##   P-value (Chi-square)                           0.001
##   Test statistic for each group:
##     woman                                       83.870
##     man                                         58.033
## 
## Model Test Baseline Model:
## 
##   Test statistic                              1378.913
##   Degrees of freedom                               110
##   P-value                                        0.000
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    0.961
##   Tucker-Lewis Index (TLI)                       0.953
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)              -3470.878
##   Loglikelihood unrestricted model (H1)      -3399.927
##                                                       
##   Akaike (AIC)                                7065.756
##   Bayesian (BIC)                              7284.087
##   Sample-size adjusted Bayesian (SABIC)       7087.541
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.066
##   90 Percent confidence interval - lower         0.043
##   90 Percent confidence interval - upper         0.087
##   P-value H_0: RMSEA <= 0.050                    0.114
##   P-value H_0: RMSEA >= 0.080                    0.137
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.058
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## 
## Group 1 [woman]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   attitudes =~                                                          
##     attit_1           1.000                               0.919    0.816
##     attit_2 (.p2.)    1.023    0.066   15.495    0.000    0.940    0.877
##     attit_3 (.p3.)   -1.016    0.066  -15.434    0.000   -0.935   -0.884
##   norms =~                                                              
##     norm_1            1.000                               0.808    0.798
##     norm_2  (.p5.)    0.956    0.083   11.551    0.000    0.772    0.766
##     norm_3  (.p6.)    0.942    0.084   11.256    0.000    0.761    0.743
##   control =~                                                            
##     cntrl_1           1.000                               0.671    0.646
##     cntrl_2 (.p8.)    0.846    0.125    6.768    0.000    0.567    0.545
##     cntrl_3 (.p9.)    1.008    0.129    7.814    0.000    0.676    0.665
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   intent ~                                                              
##     attitudes         0.436    0.082    5.335    0.000    0.401    0.403
##     norms             0.598    0.100    6.008    0.000    0.483    0.486
##   behavior ~                                                            
##     intent            0.347    0.064    5.436    0.000    0.347    0.351
##     control           0.727    0.138    5.274    0.000    0.488    0.496
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   attitudes ~~                                                          
##     norms             0.425    0.081    5.262    0.000    0.572    0.572
##     control           0.464    0.082    5.634    0.000    0.752    0.752
##   norms ~~                                                              
##     control           0.386    0.073    5.320    0.000    0.712    0.712
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .attit_1 (.31.)    2.863    0.084   34.071    0.000    2.863    2.542
##    .attit_2 (.32.)    2.884    0.082   35.225    0.000    2.884    2.690
##    .attit_3 (.33.)    3.168    0.081   39.065    0.000    3.168    2.995
##    .norm_1  (.34.)    2.802    0.076   36.874    0.000    2.802    2.767
##    .norm_2  (.35.)    2.830    0.075   37.555    0.000    2.830    2.807
##    .norm_3  (.36.)    2.796    0.076   36.725    0.000    2.796    2.730
##    .cntrl_1 (.37.)    2.855    0.077   37.078    0.000    2.855    2.749
##    .cntrl_2 (.38.)    2.866    0.076   37.909    0.000    2.866    2.753
##    .cntrl_3 (.39.)    2.897    0.076   37.969    0.000    2.897    2.849
##    .intent  (.40.)    2.712    0.078   34.861    0.000    2.712    2.726
##    .behavir (.41.)    1.630    0.175    9.289    0.000    1.630    1.658
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .attit_1           0.423    0.059    7.172    0.000    0.423    0.333
##    .attit_2           0.266    0.045    5.879    0.000    0.266    0.231
##    .attit_3           0.246    0.043    5.671    0.000    0.246    0.219
##    .norm_1            0.372    0.060    6.230    0.000    0.372    0.363
##    .norm_2            0.420    0.062    6.760    0.000    0.420    0.413
##    .norm_3            0.469    0.066    7.063    0.000    0.469    0.448
##    .control_1         0.629    0.085    7.426    0.000    0.629    0.583
##    .control_2         0.762    0.094    8.088    0.000    0.762    0.703
##    .control_3         0.577    0.080    7.238    0.000    0.577    0.558
##    .intent            0.374    0.049    7.615    0.000    0.374    0.378
##    .behavior          0.391    0.052    7.486    0.000    0.391    0.404
##     attitudes         0.845    0.129    6.561    0.000    1.000    1.000
##     norms             0.653    0.108    6.048    0.000    1.000    1.000
##     control           0.450    0.101    4.457    0.000    1.000    1.000
## 
## R-Square:
##                    Estimate
##     attit_1           0.667
##     attit_2           0.769
##     attit_3           0.781
##     norm_1            0.637
##     norm_2            0.587
##     norm_3            0.552
##     control_1         0.417
##     control_2         0.297
##     control_3         0.442
##     intent            0.622
##     behavior          0.596
## 
## 
## Group 2 [man]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   attitudes =~                                                          
##     attit_1           1.000                               0.922    0.815
##     attit_2 (.p2.)    1.023    0.066   15.495    0.000    0.943    0.817
##     attit_3 (.p3.)   -1.016    0.066  -15.434    0.000   -0.937   -0.782
##   norms =~                                                              
##     norm_1            1.000                               0.875    0.723
##     norm_2  (.p5.)    0.956    0.083   11.551    0.000    0.837    0.679
##     norm_3  (.p6.)    0.942    0.084   11.256    0.000    0.825    0.667
##   control =~                                                            
##     cntrl_1           1.000                               0.663    0.631
##     cntrl_2 (.p8.)    0.846    0.125    6.768    0.000    0.561    0.467
##     cntrl_3 (.p9.)    1.008    0.129    7.814    0.000    0.668    0.540
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   intent ~                                                              
##     attitudes         0.535    0.097    5.497    0.000    0.494    0.446
##     norms             0.858    0.111    7.702    0.000    0.751    0.679
##   behavior ~                                                            
##     intent            0.613    0.060   10.188    0.000    0.613    0.706
##     control           0.007    0.159    0.045    0.964    0.005    0.005
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   attitudes ~~                                                          
##     norms             0.060    0.108    0.552    0.581    0.074    0.074
##     control           0.426    0.107    3.978    0.000    0.697    0.697
##   norms ~~                                                              
##     control           0.220    0.096    2.291    0.022    0.380    0.380
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .attit_1 (.31.)    2.863    0.084   34.071    0.000    2.863    2.531
##    .attit_2 (.32.)    2.884    0.082   35.225    0.000    2.884    2.499
##    .attit_3 (.33.)    3.168    0.081   39.065    0.000    3.168    2.645
##    .norm_1  (.34.)    2.802    0.076   36.874    0.000    2.802    2.314
##    .norm_2  (.35.)    2.830    0.075   37.555    0.000    2.830    2.296
##    .norm_3  (.36.)    2.796    0.076   36.725    0.000    2.796    2.261
##    .cntrl_1 (.37.)    2.855    0.077   37.078    0.000    2.855    2.719
##    .cntrl_2 (.38.)    2.866    0.076   37.909    0.000    2.866    2.385
##    .cntrl_3 (.39.)    2.897    0.076   37.969    0.000    2.897    2.344
##    .intent  (.40.)    2.712    0.078   34.861    0.000    2.712    2.450
##    .behavir (.41.)    1.630    0.175    9.289    0.000    1.630    1.696
##     attitds           0.369    0.130    2.834    0.005    0.400    0.400
##     norms             0.534    0.126    4.246    0.000    0.610    0.610
##     control           0.309    0.115    2.691    0.007    0.466    0.466
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .attit_1           0.430    0.091    4.710    0.000    0.430    0.336
##    .attit_2           0.443    0.094    4.691    0.000    0.443    0.333
##    .attit_3           0.556    0.108    5.130    0.000    0.556    0.388
##    .norm_1            0.699    0.137    5.088    0.000    0.699    0.477
##    .norm_2            0.819    0.150    5.457    0.000    0.819    0.539
##    .norm_3            0.849    0.153    5.538    0.000    0.849    0.555
##    .control_1         0.663    0.135    4.908    0.000    0.663    0.602
##    .control_2         1.130    0.187    6.025    0.000    1.130    0.782
##    .control_3         1.082    0.191    5.673    0.000    1.082    0.708
##    .intent            0.363    0.089    4.091    0.000    0.363    0.296
##    .behavior          0.460    0.069    6.671    0.000    0.460    0.498
##     attitudes         0.850    0.164    5.190    0.000    1.000    1.000
##     norms             0.766    0.171    4.495    0.000    1.000    1.000
##     control           0.440    0.133    3.301    0.001    1.000    1.000
## 
## R-Square:
##                    Estimate
##     attit_1           0.664
##     attit_2           0.667
##     attit_3           0.612
##     norm_1            0.523
##     norm_2            0.461
##     norm_3            0.445
##     control_1         0.398
##     control_2         0.218
##     control_3         0.292
##     intent            0.704
##     behavior          0.502

7.4.3.4

Conduct an omnibus test to check if sex moderates any of the latent regression paths in the model from 7.4.3.3.

Click for explanation
## Estimate a restricted model wherein all latent regression paths are equated
## across groups.
toraOut0 <- sem(tora_sem, 
                data = condom, 
                group = "sex", 
                group.equal = c("loadings", "intercepts", "regressions")
                )

## Test the constraints:
anova(toraOut, toraOut0)
Click for explanation

We can equate the latent regressions by specifying the group.equal = "regressions" argument in sem(). Then, we simply compare this constrained model to the unconstrained model from 7.4.3.3 to get our test of moderation.

Equating all regression paths across groups produces a significant loss of fit (\(\Delta \chi^2[4] = 52.86\), \(p < 0.001\)). Therefore, sex must moderate at least some of these paths.


7.4.3.5

Conduct a two-parameter test to check if sex moderates the effects of intent and control on behavior.

  • Use the lavTestWald() function to conduct your test.
  • Keep only the weak invariance constraints when estimating the model.
Click to show code
## Add the structural paths to the model and assign labels:
tora_sem <- paste(tora_cfa,
                  'intent ~ attitudes + norms
                   behavior ~ c(b1f, b1m) * intent + c(b2f, b2m) * control',
                  sep = '\n')

## Estimate the model with weak invariance constraints:
toraOut <- sem(tora_sem, data = condom, group = "sex", group.equal = "loadings")

## Check the results:
summary(toraOut, fit.measures = TRUE, standardized = TRUE, rsquare = TRUE)
## lavaan 0.6-18 ended normally after 60 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        76
##   Number of equality constraints                     6
## 
##   Number of observations per group:                   
##     woman                                          161
##     man                                             89
## 
## Model Test User Model:
##                                                       
##   Test statistic                               119.722
##   Degrees of freedom                                84
##   P-value (Chi-square)                           0.006
##   Test statistic for each group:
##     woman                                       76.908
##     man                                         42.814
## 
## Model Test Baseline Model:
## 
##   Test statistic                              1378.913
##   Degrees of freedom                               110
##   P-value                                        0.000
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    0.972
##   Tucker-Lewis Index (TLI)                       0.963
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)              -3459.788
##   Loglikelihood unrestricted model (H1)      -3399.927
##                                                       
##   Akaike (AIC)                                7059.576
##   Bayesian (BIC)                              7306.078
##   Sample-size adjusted Bayesian (SABIC)       7084.172
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.058
##   90 Percent confidence interval - lower         0.032
##   90 Percent confidence interval - upper         0.081
##   P-value H_0: RMSEA <= 0.050                    0.272
##   P-value H_0: RMSEA >= 0.080                    0.058
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.047
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## 
## Group 1 [woman]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   attitudes =~                                                          
##     attit_1           1.000                               0.909    0.813
##     attit_2 (.p2.)    1.047    0.069   15.249    0.000    0.951    0.882
##     attit_3 (.p3.)   -1.025    0.068  -15.075    0.000   -0.931   -0.882
##   norms =~                                                              
##     norm_1            1.000                               0.824    0.809
##     norm_2  (.p5.)    0.936    0.083   11.256    0.000    0.771    0.768
##     norm_3  (.p6.)    0.908    0.084   10.810    0.000    0.748    0.734
##   control =~                                                            
##     cntrl_1           1.000                               0.690    0.666
##     cntrl_2 (.p8.)    0.832    0.126    6.593    0.000    0.574    0.551
##     cntrl_3 (.p9.)    1.006    0.131    7.673    0.000    0.694    0.682
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   intent ~                                                              
##     attituds          0.441    0.083    5.294    0.000    0.400    0.403
##     norms             0.580    0.098    5.918    0.000    0.478    0.480
##   behavior ~                                                            
##     intent   (b1f)    0.531    0.074    7.127    0.000    0.531    0.524
##     control  (b2f)    0.490    0.130    3.767    0.000    0.338    0.336
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   attitudes ~~                                                          
##     norms             0.428    0.081    5.266    0.000    0.572    0.572
##     control           0.454    0.082    5.517    0.000    0.723    0.723
##   norms ~~                                                              
##     control           0.384    0.074    5.169    0.000    0.676    0.676
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .attit_1           2.839    0.088   32.237    0.000    2.839    2.541
##    .attit_2           2.907    0.085   34.191    0.000    2.907    2.695
##    .attit_3           3.174    0.083   38.126    0.000    3.174    3.005
##    .norm_1            2.832    0.080   35.280    0.000    2.832    2.780
##    .norm_2            2.832    0.079   35.765    0.000    2.832    2.819
##    .norm_3            2.795    0.080   34.787    0.000    2.795    2.742
##    .control_1         2.851    0.082   34.875    0.000    2.851    2.749
##    .control_2         2.857    0.082   34.813    0.000    2.857    2.744
##    .control_3         2.888    0.080   35.985    0.000    2.888    2.836
##    .intent            2.677    0.078   34.159    0.000    2.677    2.692
##    .behavior          1.107    0.207    5.338    0.000    1.107    1.098
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .attit_1           0.423    0.059    7.208    0.000    0.423    0.339
##    .attit_2           0.259    0.045    5.713    0.000    0.259    0.223
##    .attit_3           0.248    0.044    5.701    0.000    0.248    0.222
##    .norm_1            0.359    0.060    5.989    0.000    0.359    0.346
##    .norm_2            0.415    0.062    6.711    0.000    0.415    0.411
##    .norm_3            0.479    0.067    7.152    0.000    0.479    0.461
##    .control_1         0.599    0.085    7.027    0.000    0.599    0.557
##    .control_2         0.755    0.095    7.940    0.000    0.755    0.696
##    .control_3         0.555    0.081    6.822    0.000    0.555    0.535
##    .intent            0.382    0.050    7.657    0.000    0.382    0.386
##    .behavior          0.402    0.049    8.152    0.000    0.402    0.396
##     attitudes         0.825    0.127    6.495    0.000    1.000    1.000
##     norms             0.679    0.112    6.066    0.000    1.000    1.000
##     control           0.477    0.106    4.483    0.000    1.000    1.000
## 
## R-Square:
##                    Estimate
##     attit_1           0.661
##     attit_2           0.777
##     attit_3           0.778
##     norm_1            0.654
##     norm_2            0.589
##     norm_3            0.539
##     control_1         0.443
##     control_2         0.304
##     control_3         0.465
##     intent            0.614
##     behavior          0.604
## 
## 
## Group 2 [man]:
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   attitudes =~                                                          
##     attit_1           1.000                               0.921    0.812
##     attit_2 (.p2.)    1.047    0.069   15.249    0.000    0.964    0.831
##     attit_3 (.p3.)   -1.025    0.068  -15.075    0.000   -0.944   -0.787
##   norms =~                                                              
##     norm_1            1.000                               0.928    0.753
##     norm_2  (.p5.)    0.936    0.083   11.256    0.000    0.869    0.698
##     norm_3  (.p6.)    0.908    0.084   10.810    0.000    0.843    0.676
##   control =~                                                            
##     cntrl_1           1.000                               0.669    0.634
##     cntrl_2 (.p8.)    0.832    0.126    6.593    0.000    0.556    0.464
##     cntrl_3 (.p9.)    1.006    0.131    7.673    0.000    0.673    0.547
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   intent ~                                                              
##     attituds          0.501    0.098    5.134    0.000    0.462    0.432
##     norms             0.749    0.112    6.696    0.000    0.695    0.649
##   behavior ~                                                            
##     intent   (b1m)    0.344    0.086    4.005    0.000    0.344    0.453
##     control  (b2m)    0.307    0.168    1.830    0.067    0.205    0.253
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   attitudes ~~                                                          
##     norms             0.084    0.113    0.742    0.458    0.098    0.098
##     control           0.424    0.107    3.960    0.000    0.688    0.688
##   norms ~~                                                              
##     control           0.240    0.102    2.361    0.018    0.387    0.387
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .attit_1           3.270    0.120   27.179    0.000    3.270    2.881
##    .attit_2           3.180    0.123   25.848    0.000    3.180    2.740
##    .attit_3           2.787    0.127   21.900    0.000    2.787    2.321
##    .norm_1            3.236    0.131   24.790    0.000    3.236    2.628
##    .norm_2            3.337    0.132   25.309    0.000    3.337    2.683
##    .norm_3            3.303    0.132   24.992    0.000    3.303    2.649
##    .control_1         3.157    0.112   28.223    0.000    3.157    2.992
##    .control_2         3.135    0.127   24.653    0.000    3.135    2.613
##    .control_3         3.213    0.130   24.627    0.000    3.213    2.610
##    .intent            3.427    0.113   30.233    0.000    3.427    3.205
##    .behavior          2.607    0.303    8.614    0.000    2.607    3.211
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .attit_1           0.439    0.092    4.795    0.000    0.439    0.341
##    .attit_2           0.417    0.092    4.518    0.000    0.417    0.310
##    .attit_3           0.549    0.107    5.120    0.000    0.549    0.381
##    .norm_1            0.656    0.137    4.801    0.000    0.656    0.432
##    .norm_2            0.792    0.148    5.342    0.000    0.792    0.512
##    .norm_3            0.845    0.153    5.504    0.000    0.845    0.543
##    .control_1         0.666    0.134    4.955    0.000    0.666    0.598
##    .control_2         1.130    0.187    6.053    0.000    1.130    0.785
##    .control_3         1.063    0.187    5.669    0.000    1.063    0.701
##    .intent            0.385    0.086    4.471    0.000    0.385    0.337
##    .behavior          0.399    0.063    6.328    0.000    0.399    0.605
##     attitudes         0.849    0.164    5.174    0.000    1.000    1.000
##     norms             0.861    0.190    4.528    0.000    1.000    1.000
##     control           0.447    0.134    3.334    0.001    1.000    1.000
## 
## R-Square:
##                    Estimate
##     attit_1           0.659
##     attit_2           0.690
##     attit_3           0.619
##     norm_1            0.568
##     norm_2            0.488
##     norm_3            0.457
##     control_1         0.402
##     control_2         0.215
##     control_3         0.299
##     intent            0.663
##     behavior          0.395
## Test for moderation:
lavTestWald(toraOut, "b1f == b1m; b2f == b2m")
## $stat
## [1] 9.85773
## 
## $df
## [1] 2
## 
## $p.value
## [1] 0.00723471
## 
## $se
## [1] "standard"
Click for explanation

The Wald test suggest significant moderation (\(\Delta \chi^2[2] = 9.86\), \(p = 0.007\)). Equating these two regression slopes across groups produces a significant loss of fit. Therefore, sex must moderate one or both of these paths.


End of In-Class Exercises