Import the dataset

library(readxl)
config2data <- read_excel("configural_2_data.xlsx")
View(config2data)

Call the lavaan package

library(lavaan)
## This is lavaan 0.6-7
## lavaan is BETA software! Please report any bugs.

Specify the factor structure

config.model <- '
  sa1 =~ au7t1 + au2t1 + au10t1 +au12t1
  sa2 =~ au7t2 + au2t2 + au10t2 +au12t2
  '

Specify the configural model

fit <- cfa(config.model, data=config2data)

Take a look at the model summary with model fit statistics

summary(fit,fit.measures=TRUE)
## lavaan 0.6-7 ended normally after 31 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of free parameters                         17
##                                                       
##   Number of observations                           173
##                                                       
## Model Test User Model:
##                                                       
##   Test statistic                                48.616
##   Degrees of freedom                                19
##   P-value (Chi-square)                           0.000
## 
## Model Test Baseline Model:
## 
##   Test statistic                               593.976
##   Degrees of freedom                                28
##   P-value                                        0.000
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    0.948
##   Tucker-Lewis Index (TLI)                       0.923
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)              -2111.230
##   Loglikelihood unrestricted model (H1)      -2086.922
##                                                       
##   Akaike (AIC)                                4256.460
##   Bayesian (BIC)                              4310.066
##   Sample-size adjusted Bayesian (BIC)         4256.234
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.095
##   90 Percent confidence interval - lower         0.062
##   90 Percent confidence interval - upper         0.128
##   P-value RMSEA <= 0.05                          0.014
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.056
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   sa1 =~                                              
##     au7t1             1.000                           
##     au2t1             0.783    0.140    5.593    0.000
##     au10t1            1.224    0.149    8.194    0.000
##     au12t1            1.170    0.144    8.145    0.000
##   sa2 =~                                              
##     au7t2             1.000                           
##     au2t2             0.819    0.115    7.108    0.000
##     au10t2            1.097    0.109   10.049    0.000
##     au12t2            1.018    0.104    9.789    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   sa1 ~~                                              
##     sa2               0.616    0.120    5.126    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .au7t1             1.341    0.163    8.219    0.000
##    .au2t1             1.663    0.190    8.774    0.000
##    .au10t1            0.603    0.110    5.490    0.000
##    .au12t1            0.604    0.104    5.793    0.000
##    .au7t2             0.835    0.109    7.669    0.000
##    .au2t2             1.230    0.143    8.575    0.000
##    .au10t2            0.457    0.081    5.653    0.000
##    .au12t2            0.502    0.078    6.396    0.000
##     sa1               0.881    0.205    4.292    0.000
##     sa2               0.930    0.178    5.219    0.000

If we want to look at specific data-model fit measures, we can do this

fitmeasures(fit, c("chisq","df","pvalue","cfi","tli","rmsea","rmsea.ci.lower","rmsea.ci.upper","AIC","srmr"))
##          chisq             df         pvalue            cfi            tli 
##         48.616         19.000          0.000          0.948          0.923 
##          rmsea rmsea.ci.lower rmsea.ci.upper            aic           srmr 
##          0.095          0.062          0.128       4256.460          0.056

Since our model fit does not look very good, let’s do the model tweaks recommended by Widaman et al. (2010)

tweak.model <- '
  sa1 =~ a*1*au7t1 + au2t1 + au10t1 +au12t1  #fix au7t1 loading to 1 and label it as a
  sa2 =~ a*1*au7t2 + au2t2 + au10t2 +au12t2  #fix au7t2 loading to 1 and label it as a
  sa1 ~ 0*1          #fix the mean of sa1 at 0
  sa1 ~~ 1*sa1       #fix the variance of sa1 to 1
  au7t1 ~ b*1        #fix the mean of au7t1 to 1 and label it as b
  au7t2 ~ b*1        #fix the mean of au7t2 to 1 and label it as b
  au7t1 ~~ au7t2     #correlate the two variables
  au2t1 ~~ au2t2     #correlate the two variables
  au10t1 ~~ au10t2   #correlate the two variables
  au12t1 ~~ au12t2   #correlate the two variables
  '

Specify this configural model with tweaks

fit1 <- cfa(tweak.model, data=config2data)

Take a look at the model summary with model fit statistics

summary(fit1,fit.measures=TRUE)
## lavaan 0.6-7 ended normally after 37 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of free parameters                         28
##   Number of equality constraints                     1
##                                                       
##   Number of observations                           173
##                                                       
## Model Test User Model:
##                                                       
##   Test statistic                                32.429
##   Degrees of freedom                                17
##   P-value (Chi-square)                           0.013
## 
## Model Test Baseline Model:
## 
##   Test statistic                               593.976
##   Degrees of freedom                                28
##   P-value                                        0.000
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    0.973
##   Tucker-Lewis Index (TLI)                       0.955
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)              -2103.136
##   Loglikelihood unrestricted model (H1)      -2086.922
##                                                       
##   Akaike (AIC)                                4260.272
##   Bayesian (BIC)                              4345.411
##   Sample-size adjusted Bayesian (BIC)         4259.914
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.072
##   90 Percent confidence interval - lower         0.032
##   90 Percent confidence interval - upper         0.110
##   P-value RMSEA <= 0.05                          0.153
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.047
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   sa1 =~                                              
##     au7t1      (a)    1.000                           
##     au2t1             0.735    0.112    6.558    0.000
##     au10t1            1.158    0.090   12.847    0.000
##     au12t1            1.123    0.089   12.670    0.000
##   sa2 =~                                              
##     au7t2      (a)    1.000                           
##     au2t2             0.806    0.113    7.140    0.000
##     au10t2            1.099    0.108   10.217    0.000
##     au12t2            1.025    0.103    9.922    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##  .au7t1 ~~                                            
##    .au7t2             0.286    0.097    2.946    0.003
##  .au2t1 ~~                                            
##    .au2t2             0.233    0.117    1.982    0.047
##  .au10t1 ~~                                           
##    .au10t2            0.113    0.066    1.697    0.090
##  .au12t1 ~~                                           
##    .au12t2            0.007    0.062    0.120    0.905
##   sa1 ~~                                              
##     sa2               0.635    0.086    7.376    0.000
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##     sa1               0.000                           
##    .au7t1      (b)    3.460    0.092   37.716    0.000
##    .au7t2      (b)    3.460    0.092   37.716    0.000
##    .au2t1             3.216    0.112   28.631    0.000
##    .au10t1            2.915    0.104   28.018    0.000
##    .au12t1            2.685    0.101   26.574    0.000
##    .au2t2             3.296    0.102   32.220    0.000
##    .au10t2            2.974    0.095   31.401    0.000
##    .au12t2            2.845    0.091   31.252    0.000
##     sa2               0.000                           
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##     sa1               1.000                           
##    .au7t1             1.358    0.165    8.223    0.000
##    .au2t1             1.674    0.191    8.780    0.000
##    .au10t1            0.609    0.114    5.327    0.000
##    .au12t1            0.578    0.109    5.288    0.000
##    .au7t2             0.837    0.110    7.617    0.000
##    .au2t2             1.228    0.143    8.571    0.000
##    .au10t2            0.469    0.085    5.495    0.000
##    .au12t2            0.492    0.082    6.013    0.000
##     sa2               0.936    0.172    5.456    0.000

Pull out the data-model fit measures

fitmeasures(fit1, c("chisq","df","pvalue","cfi","tli","rmsea","rmsea.ci.lower","rmsea.ci.upper","AIC","srmr"))
##          chisq             df         pvalue            cfi            tli 
##         32.429         17.000          0.013          0.973          0.955 
##          rmsea rmsea.ci.lower rmsea.ci.upper            aic           srmr 
##          0.072          0.032          0.110       4260.272          0.047

We can also plot the model

library(lavaanPlot)
lavaanPlot(model = fit1, node_options = list(shape = "box"), edge_options = list(color = "blue"), coefs = TRUE, covs = TRUE)
Here are some frequently used syntax in lavaan:

predict, used for regression of observed outcome to observed predictors
=~ indicator, used for latent variable to observed indicator in factor analysis measurement models
~~ covariance
~1 intercept or mean (e.g., q01 ~ 1 estimates the mean of variable q01)
1* fixes parameter or loading to one
NA* frees parameter or loading (useful to override default marker method)
a* labels the parameter ‘a’, used for model constraints