This project is a Comparison between ESEM and CFA methods to test the measurement invariance of 213 Egyptian students on Big five personality scale (30 items)

Plz Feel Free to messege me for any advice or recommendations at vet.m.mohamed@gmail.com

Loading the important package

library(lavaan) ; library(GPArotation) ; library(knitr) ; library(knitLatex) ; library(readxl) ; library(ggplot2) ;library(tidyr) ; library(dplyr) ; library(magrittr) ; library(car) ; library(psych) ; library(kableExtra) ; library(semPlot) ; library(semTools)

Reading the data and importing it

big<-read_excel(path = "./data sets/big5.xlsx")

Looking at the data structure

str(big)
## Classes 'tbl_df', 'tbl' and 'data.frame':    225 obs. of  33 variables:
##  $ serial: num  1 2 3 4 5 6 7 8 9 10 ...
##  $ Age   : num  18 19 18 19 18 22 22 18 23 19 ...
##  $ Sex   : num  1 1 1 1 1 1 1 1 1 1 ...
##  $ E1    : num  3 3 3 2 2 4 1 2 3 2 ...
##  $ E2    : num  3 2 4 3 3 4 4 4 3 1 ...
##  $ E3    : num  2 4 3 2 2 4 4 3 3 2 ...
##  $ E4    : num  3 2 4 2 3 4 4 4 3 4 ...
##  $ E6    : num  4 4 1 3 3 4 1 4 3 2 ...
##  $ E7    : num  3 3 4 3 3 4 4 2 2 4 ...
##  $ N1    : num  2 2 4 4 3 2 4 1 2 2 ...
##  $ N2    : num  1 2 1 2 2 3 2 1 2 1 ...
##  $ N3    : num  1 2 2 2 2 2 1 1 2 1 ...
##  $ N5    : num  3 2 1 2 4 3 4 1 3 4 ...
##  $ N8    : num  4 2 1 2 2 3 4 1 2 2 ...
##  $ N9    : num  1 2 2 2 1 2 4 1 2 4 ...
##  $ A1    : num  3 3 4 3 3 4 1 4 3 1 ...
##  $ A2    : num  3 3 2 4 2 4 2 4 2 1 ...
##  $ A3    : num  4 2 3 4 3 3 3 4 3 2 ...
##  $ A4    : num  3 3 3 4 4 4 3 4 3 2 ...
##  $ A5    : num  3 2 3 4 4 4 4 3 4 2 ...
##  $ A6    : num  3 3 3 4 2 4 1 4 2 2 ...
##  $ O2    : num  3 2 4 3 4 3 4 3 4 2 ...
##  $ O3    : num  3 1 3 1 2 2 1 4 3 2 ...
##  $ O4    : num  1 2 4 3 3 4 4 4 2 2 ...
##  $ O5    : num  2 3 4 3 4 3 1 4 2 2 ...
##  $ O6    : num  3 4 3 3 3 3 4 3 2 2 ...
##  $ O8    : num  4 3 3 3 4 4 4 4 2 2 ...
##  $ C3    : num  4 2 4 3 2 3 4 4 3 2 ...
##  $ C4    : num  2 4 4 3 4 4 4 4 3 2 ...
##  $ C5    : num  3 3 2 3 4 4 1 4 3 2 ...
##  $ C6    : num  4 2 3 2 3 4 1 4 2 2 ...
##  $ C7    : num  2 2 3 3 4 4 1 4 3 3 ...
##  $ C8    : num  2 3 2 3 3 4 1 4 4 1 ...

We need to remove “serial” and convert “sex” to factor Male and female

big<-big[,-1]

big$Sex<-factor(x = big$Sex,levels = c(1,2),labels = c("male","female"))

kable(head(big),format = "markdown")
Age Sex E1 E2 E3 E4 E6 E7 N1 N2 N3 N5 N8 N9 A1 A2 A3 A4 A5 A6 O2 O3 O4 O5 O6 O8 C3 C4 C5 C6 C7 C8
18 male 3 3 2 3 4 3 2 1 1 3 4 1 3 3 4 3 3 3 3 3 1 2 3 4 4 2 3 4 2 2
19 male 3 2 4 2 4 3 2 2 2 2 2 2 3 3 2 3 2 3 2 1 2 3 4 3 2 4 3 2 2 3
18 male 3 4 3 4 1 4 4 1 2 1 1 2 4 2 3 3 3 3 4 3 4 4 3 3 4 4 2 3 3 2
19 male 2 3 2 2 3 3 4 2 2 2 2 2 3 4 4 4 4 4 3 1 3 3 3 3 3 3 3 2 3 3
18 male 2 3 2 3 3 3 3 2 2 4 2 1 3 2 3 4 4 2 4 2 3 4 3 4 2 4 4 3 4 3
22 male 4 4 4 4 4 4 2 3 2 3 3 2 4 4 3 4 4 4 3 2 4 3 3 4 3 4 4 4 4 4

Now lets look at some summary for the data over all

summary(big) #Foor accurecy, out bound items and missing data 
##       Age            Sex            E1              E2       
##  Min.   :17.00   male  :114   Min.   :1.000   Min.   :1.000  
##  1st Qu.:18.00   female:111   1st Qu.:2.000   1st Qu.:2.000  
##  Median :19.00                Median :2.000   Median :3.000  
##  Mean   :20.21                Mean   :2.551   Mean   :2.538  
##  3rd Qu.:20.00                3rd Qu.:3.000   3rd Qu.:3.000  
##  Max.   :40.00                Max.   :4.000   Max.   :4.000  
##        E3              E4              E6              E7       
##  Min.   :1.000   Min.   :1.000   Min.   :1.000   Min.   :1.000  
##  1st Qu.:2.000   1st Qu.:2.000   1st Qu.:3.000   1st Qu.:2.000  
##  Median :2.000   Median :3.000   Median :3.000   Median :3.000  
##  Mean   :2.569   Mean   :2.667   Mean   :3.196   Mean   :2.889  
##  3rd Qu.:3.000   3rd Qu.:3.000   3rd Qu.:4.000   3rd Qu.:4.000  
##  Max.   :4.000   Max.   :4.000   Max.   :4.000   Max.   :4.000  
##        N1              N2              N3             N5       
##  Min.   :1.000   Min.   :1.000   Min.   :1.00   Min.   :1.000  
##  1st Qu.:2.000   1st Qu.:1.000   1st Qu.:1.00   1st Qu.:2.000  
##  Median :2.000   Median :2.000   Median :2.00   Median :2.000  
##  Mean   :2.356   Mean   :1.942   Mean   :1.96   Mean   :2.302  
##  3rd Qu.:3.000   3rd Qu.:2.000   3rd Qu.:2.00   3rd Qu.:3.000  
##  Max.   :4.000   Max.   :4.000   Max.   :4.00   Max.   :4.000  
##        N8              N9              A1              A2       
##  Min.   :1.000   Min.   :1.000   Min.   :1.000   Min.   :1.000  
##  1st Qu.:1.000   1st Qu.:1.000   1st Qu.:3.000   1st Qu.:2.000  
##  Median :2.000   Median :2.000   Median :4.000   Median :3.000  
##  Mean   :2.013   Mean   :1.973   Mean   :3.293   Mean   :2.893  
##  3rd Qu.:3.000   3rd Qu.:2.000   3rd Qu.:4.000   3rd Qu.:4.000  
##  Max.   :4.000   Max.   :4.000   Max.   :4.000   Max.   :4.000  
##        A3              A4              A5              A6       
##  Min.   :1.000   Min.   :1.000   Min.   :1.000   Min.   :1.000  
##  1st Qu.:2.000   1st Qu.:3.000   1st Qu.:3.000   1st Qu.:2.000  
##  Median :3.000   Median :4.000   Median :3.000   Median :3.000  
##  Mean   :3.142   Mean   :3.493   Mean   :3.342   Mean   :3.138  
##  3rd Qu.:4.000   3rd Qu.:4.000   3rd Qu.:4.000   3rd Qu.:4.000  
##  Max.   :4.000   Max.   :4.000   Max.   :4.000   Max.   :4.000  
##        O2              O3              O4              O5       
##  Min.   :1.000   Min.   :1.000   Min.   :1.000   Min.   :1.000  
##  1st Qu.:2.000   1st Qu.:2.000   1st Qu.:2.000   1st Qu.:2.000  
##  Median :3.000   Median :3.000   Median :3.000   Median :3.000  
##  Mean   :2.769   Mean   :2.533   Mean   :2.693   Mean   :3.062  
##  3rd Qu.:4.000   3rd Qu.:3.000   3rd Qu.:4.000   3rd Qu.:4.000  
##  Max.   :4.000   Max.   :4.000   Max.   :4.000   Max.   :4.000  
##        O6             O8              C3              C4       
##  Min.   :1.00   Min.   :1.000   Min.   :1.000   Min.   :1.000  
##  1st Qu.:2.00   1st Qu.:3.000   1st Qu.:2.000   1st Qu.:2.000  
##  Median :3.00   Median :4.000   Median :3.000   Median :3.000  
##  Mean   :2.88   Mean   :3.338   Mean   :2.782   Mean   :3.071  
##  3rd Qu.:4.00   3rd Qu.:4.000   3rd Qu.:4.000   3rd Qu.:4.000  
##  Max.   :4.00   Max.   :4.000   Max.   :4.000   Max.   :4.000  
##        C5             C6              C7             C8       
##  Min.   :1.00   Min.   :1.000   Min.   :1.00   Min.   :1.000  
##  1st Qu.:2.00   1st Qu.:2.000   1st Qu.:2.00   1st Qu.:3.000  
##  Median :3.00   Median :3.000   Median :3.00   Median :3.000  
##  Mean   :3.04   Mean   :2.844   Mean   :2.84   Mean   :2.973  
##  3rd Qu.:4.00   3rd Qu.:4.000   3rd Qu.:4.00   3rd Qu.:4.000  
##  Max.   :4.00   Max.   :4.000   Max.   :4.00   Max.   :4.000

Great , the there is no out of bound items or missing data , and the number of males and females is all most equal

The normality and linearity assumption is critical for Factor analysis and SEM , So, Lets test it

#Testing Multivariate Normality using QQplot From fake regression on random normal variable
set.seed(0124)
rn<-rnorm(n = nrow(big))
lm<-lm(rn~.,data = big[,-c(1,2)])

plot(lm,1) #Homogeniety

qqPlot(lm) # Normality and linearity

## [1]  85 223

From The QQplot we can see that we can assume the normality and linearity of the data !!

The following steps include conducting EFA

Lets start :

Firstly lets test the assumptions : Additivity , sample adequacy

#Additivity 

corr<-cor(x = big[,-c(1,2)],method = "p")

kable(corr,digits = 2,format = "markdown") #correlation table
E1 E2 E3 E4 E6 E7 N1 N2 N3 N5 N8 N9 A1 A2 A3 A4 A5 A6 O2 O3 O4 O5 O6 O8 C3 C4 C5 C6 C7 C8
E1 1.00 0.39 0.55 0.43 0.44 0.35 -0.11 -0.07 -0.21 -0.17 -0.02 -0.21 0.03 0.09 0.08 0.11 0.18 0.18 0.08 0.05 0.03 0.14 0.11 0.24 0.10 0.16 0.18 0.05 0.10 0.06
E2 0.39 1.00 0.44 0.26 0.32 0.39 -0.09 -0.18 -0.24 -0.12 -0.02 -0.25 0.05 0.07 0.10 0.13 0.22 0.18 0.12 0.06 0.18 0.06 0.11 0.32 0.06 0.12 0.24 0.02 0.09 0.06
E3 0.55 0.44 1.00 0.35 0.42 0.47 -0.12 -0.19 -0.32 -0.13 -0.06 -0.24 0.10 0.06 0.05 0.12 0.24 0.18 0.16 0.14 0.22 0.20 0.20 0.26 0.23 0.23 0.18 0.14 0.25 0.14
E4 0.43 0.26 0.35 1.00 0.27 0.39 -0.08 -0.11 -0.20 -0.02 0.01 -0.11 0.00 0.13 0.13 0.17 0.24 0.21 0.13 0.11 0.17 0.18 0.13 0.18 0.09 0.22 0.11 0.03 0.07 0.05
E6 0.44 0.32 0.42 0.27 1.00 0.35 -0.15 -0.29 -0.44 -0.33 -0.15 -0.49 -0.04 0.09 -0.02 0.09 0.08 0.09 -0.08 0.05 -0.03 0.09 0.09 0.16 0.02 0.07 0.16 0.08 0.05 0.16
E7 0.35 0.39 0.47 0.39 0.35 1.00 -0.05 -0.20 -0.31 -0.13 -0.03 -0.26 0.10 0.06 0.12 0.19 0.28 0.21 0.19 0.09 0.13 0.21 0.18 0.29 0.15 0.30 0.27 -0.02 0.14 0.04
N1 -0.11 -0.09 -0.12 -0.08 -0.15 -0.05 1.00 0.41 0.35 0.49 0.33 0.16 0.02 0.06 0.00 0.04 0.05 0.01 -0.10 0.01 -0.11 -0.10 -0.11 0.03 -0.04 -0.12 -0.10 -0.14 -0.10 -0.23
N2 -0.07 -0.18 -0.19 -0.11 -0.29 -0.20 0.41 1.00 0.55 0.43 0.28 0.37 0.11 0.02 0.08 0.00 0.08 0.11 0.02 -0.05 -0.03 -0.09 -0.08 -0.05 0.02 -0.12 -0.04 0.00 -0.02 -0.04
N3 -0.21 -0.24 -0.32 -0.20 -0.44 -0.31 0.35 0.55 1.00 0.37 0.30 0.51 0.05 0.08 0.11 0.03 0.01 0.02 0.02 -0.02 -0.03 -0.07 -0.04 -0.12 0.05 -0.18 -0.09 0.01 -0.10 -0.14
N5 -0.17 -0.12 -0.13 -0.02 -0.33 -0.13 0.49 0.43 0.37 1.00 0.52 0.36 -0.03 -0.03 0.03 -0.03 0.01 -0.07 -0.14 -0.02 -0.03 -0.16 -0.14 -0.02 -0.01 -0.11 -0.11 -0.11 -0.09 -0.16
N8 -0.02 -0.02 -0.06 0.01 -0.15 -0.03 0.33 0.28 0.30 0.52 1.00 0.30 -0.09 0.01 0.02 -0.01 0.05 -0.03 -0.11 -0.10 -0.05 -0.13 -0.05 0.02 0.03 -0.15 -0.13 -0.13 -0.20 -0.25
N9 -0.21 -0.25 -0.24 -0.11 -0.49 -0.26 0.16 0.37 0.51 0.36 0.30 1.00 0.04 0.02 0.10 0.02 -0.04 -0.06 0.02 0.02 -0.01 -0.09 -0.05 -0.07 0.04 -0.11 -0.15 -0.08 -0.06 -0.13
A1 0.03 0.05 0.10 0.00 -0.04 0.10 0.02 0.11 0.05 -0.03 -0.09 0.04 1.00 0.34 0.41 0.38 0.36 0.39 0.14 0.23 0.21 0.17 0.01 0.19 0.22 0.17 0.16 0.33 0.34 0.18
A2 0.09 0.07 0.06 0.13 0.09 0.06 0.06 0.02 0.08 -0.03 0.01 0.02 0.34 1.00 0.47 0.31 0.34 0.36 0.07 0.08 0.12 0.17 0.13 0.15 0.13 0.10 0.10 0.12 0.17 0.14
A3 0.08 0.10 0.05 0.13 -0.02 0.12 0.00 0.08 0.11 0.03 0.02 0.10 0.41 0.47 1.00 0.43 0.49 0.39 0.13 0.18 0.19 0.18 0.12 0.26 0.26 0.08 0.16 0.22 0.27 0.11
A4 0.11 0.13 0.12 0.17 0.09 0.19 0.04 0.00 0.03 -0.03 -0.01 0.02 0.38 0.31 0.43 1.00 0.54 0.41 0.08 0.18 0.22 0.24 0.16 0.24 0.18 0.18 0.22 0.18 0.26 0.16
A5 0.18 0.22 0.24 0.24 0.08 0.28 0.05 0.08 0.01 0.01 0.05 -0.04 0.36 0.34 0.49 0.54 1.00 0.51 0.24 0.16 0.31 0.23 0.18 0.28 0.31 0.34 0.36 0.26 0.36 0.18
A6 0.18 0.18 0.18 0.21 0.09 0.21 0.01 0.11 0.02 -0.07 -0.03 -0.06 0.39 0.36 0.39 0.41 0.51 1.00 0.15 0.18 0.33 0.23 0.19 0.21 0.24 0.29 0.36 0.38 0.28 0.27
O2 0.08 0.12 0.16 0.13 -0.08 0.19 -0.10 0.02 0.02 -0.14 -0.11 0.02 0.14 0.07 0.13 0.08 0.24 0.15 1.00 0.39 0.49 0.48 0.35 0.10 0.30 0.31 0.27 0.21 0.30 0.25
O3 0.05 0.06 0.14 0.11 0.05 0.09 0.01 -0.05 -0.02 -0.02 -0.10 0.02 0.23 0.08 0.18 0.18 0.16 0.18 0.39 1.00 0.30 0.34 0.22 0.19 0.23 0.14 0.10 0.19 0.21 0.18
O4 0.03 0.18 0.22 0.17 -0.03 0.13 -0.11 -0.03 -0.03 -0.03 -0.05 -0.01 0.21 0.12 0.19 0.22 0.31 0.33 0.49 0.30 1.00 0.54 0.36 0.27 0.36 0.25 0.31 0.27 0.27 0.25
O5 0.14 0.06 0.20 0.18 0.09 0.21 -0.10 -0.09 -0.07 -0.16 -0.13 -0.09 0.17 0.17 0.18 0.24 0.23 0.23 0.48 0.34 0.54 1.00 0.36 0.30 0.24 0.25 0.29 0.20 0.30 0.28
O6 0.11 0.11 0.20 0.13 0.09 0.18 -0.11 -0.08 -0.04 -0.14 -0.05 -0.05 0.01 0.13 0.12 0.16 0.18 0.19 0.35 0.22 0.36 0.36 1.00 0.26 0.37 0.28 0.27 0.28 0.27 0.26
O8 0.24 0.32 0.26 0.18 0.16 0.29 0.03 -0.05 -0.12 -0.02 0.02 -0.07 0.19 0.15 0.26 0.24 0.28 0.21 0.10 0.19 0.27 0.30 0.26 1.00 0.20 0.24 0.29 0.18 0.20 0.08
C3 0.10 0.06 0.23 0.09 0.02 0.15 -0.04 0.02 0.05 -0.01 0.03 0.04 0.22 0.13 0.26 0.18 0.31 0.24 0.30 0.23 0.36 0.24 0.37 0.20 1.00 0.39 0.37 0.48 0.47 0.26
C4 0.16 0.12 0.23 0.22 0.07 0.30 -0.12 -0.12 -0.18 -0.11 -0.15 -0.11 0.17 0.10 0.08 0.18 0.34 0.29 0.31 0.14 0.25 0.25 0.28 0.24 0.39 1.00 0.59 0.30 0.38 0.30
C5 0.18 0.24 0.18 0.11 0.16 0.27 -0.10 -0.04 -0.09 -0.11 -0.13 -0.15 0.16 0.10 0.16 0.22 0.36 0.36 0.27 0.10 0.31 0.29 0.27 0.29 0.37 0.59 1.00 0.43 0.50 0.37
C6 0.05 0.02 0.14 0.03 0.08 -0.02 -0.14 0.00 0.01 -0.11 -0.13 -0.08 0.33 0.12 0.22 0.18 0.26 0.38 0.21 0.19 0.27 0.20 0.28 0.18 0.48 0.30 0.43 1.00 0.66 0.43
C7 0.10 0.09 0.25 0.07 0.05 0.14 -0.10 -0.02 -0.10 -0.09 -0.20 -0.06 0.34 0.17 0.27 0.26 0.36 0.28 0.30 0.21 0.27 0.30 0.27 0.20 0.47 0.38 0.50 0.66 1.00 0.42
C8 0.06 0.06 0.14 0.05 0.16 0.04 -0.23 -0.04 -0.14 -0.16 -0.25 -0.13 0.18 0.14 0.11 0.16 0.18 0.27 0.25 0.18 0.25 0.28 0.26 0.08 0.26 0.30 0.37 0.43 0.42 1.00
corr%>%apply(MARGIN = 2,function(x){
any(x<1&x>=abs(.9))
}) #Testing if there are a correlation over .9 between the items to avoid multicolinearity 
##    E1    E2    E3    E4    E6    E7    N1    N2    N3    N5    N8    N9 
## FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE 
##    A1    A2    A3    A4    A5    A6    O2    O3    O4    O5    O6    O8 
## FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE 
##    C3    C4    C5    C6    C7    C8 
## FALSE FALSE FALSE FALSE FALSE FALSE
#Enough correlation & Sample adequacy
cortest.bartlett(R = corr,n = nrow(big))$p.value#correlation bartelett test 
## [1] 7.124156e-269
KMO(corr)$MSA #Kaiser-Meyer-Olkin test 
## [1] 0.8278375

since the assumptions have been met ( sig cor Bartlett and MSA >.8 and no additive ), Now we can run EFA

AS there are a priori theory which assume the presence of 5 factors on which the items load in unique way , there is no need to test the number of factors

but lets do it for fun !!

facno<-fa.parallel(x = big[,-c(1,2)],fm = "ml",fa = "fa") # as th data is normal , we choosed the Muximum likelihood method of Extraction 

## Parallel analysis suggests that the number of factors =  5  and the number of components =  NA

The parallel test suggest 5 factors !! agreeing with the theory , but for fancy lets look at scree plot & Kaiser Criterion

(facno$fa.values>.7)%>%sum() #Kaiser criterion suggest 5 Factors !!
## [1] 5
plot(facno) #Scree plot Suggest 4 Factors with almost more one !!

As we see that Kaiser criterion of Eigen value suggest 5 factors and scree suggests 4 and almost one !! so we will consider those 5 !!

fit<-fa(r = big[,-c(1,2)],nfactors = 5,rotate = "geominQ",fm = "ml") 
fa.diagram(fit,main = "diagram illustrating the EFA Model")

The theory says that the factors are uncorrelated and it is supposed to use “Orthogonal” rotation Neverthless we will use oblique (oblimin geomin) Rotation , which allows the factors to correlate and that to match the default rotation method in M-Plus for ESEM and also since the data is normal , so we used maximum likelihood Extraction method

fit$loadings%>%matrix(ncol = 5,dimnames = list(c(names(big[,-c(1,2)])),paste0("F",1:5)))%>%kable(format = "markdown",digits = 3,caption = "Factor Items loading",row.names = T)
F1 F2 F3 F4 F5
E1 0.659 0.023 0.019 0.007 -0.067
E2 0.570 -0.042 0.069 -0.029 0.016
E3 0.684 0.122 -0.056 -0.003 0.053
E4 0.501 -0.100 0.106 0.039 0.111
E6 0.588 0.037 0.022 -0.315 -0.221
E7 0.622 -0.076 0.086 -0.033 0.113
N1 0.018 -0.059 0.037 0.554 -0.096
N2 -0.193 0.093 0.049 0.591 -0.027
N3 -0.402 0.019 0.084 0.548 0.070
N5 -0.017 0.029 -0.100 0.735 -0.064
N8 0.127 -0.092 -0.053 0.625 -0.055
N9 -0.365 -0.045 0.035 0.461 0.141
A1 -0.110 0.182 0.547 -0.031 -0.036
A2 -0.015 -0.070 0.611 -0.044 -0.029
A3 -0.053 -0.005 0.714 0.020 -0.001
A4 0.064 -0.024 0.656 -0.026 0.015
A5 0.200 0.110 0.587 0.106 0.054
A6 0.111 0.196 0.524 0.020 0.002
O2 -0.048 0.059 -0.060 -0.006 0.730
O3 -0.024 0.024 0.108 -0.023 0.415
O4 0.009 0.066 0.081 0.023 0.643
O5 0.028 -0.018 0.104 -0.116 0.652
O6 0.093 0.205 -0.053 -0.013 0.405
O8 0.318 0.061 0.183 0.065 0.149
C3 0.066 0.534 -0.014 0.166 0.188
C4 0.212 0.389 -0.018 -0.021 0.187
C5 0.203 0.531 0.015 0.009 0.097
C6 -0.084 0.860 0.031 -0.020 -0.104
C7 0.013 0.750 0.075 -0.023 0.006
C8 -0.035 0.456 0.034 -0.195 0.107
fit$r.scores%>%matrix(nrow = 5,dimnames = list(c(paste0("f",1:5)),c(paste0("f",1:5))))%>%kable(format = "markdown",digits = 3,caption = "factor correlation")
f1 f2 f3 f4 f5
f1 1.000 0.211 0.247 -0.222 0.286
f2 0.211 1.000 0.477 -0.149 0.522
f3 0.247 0.477 1.000 0.152 0.395
f4 -0.222 -0.149 0.152 1.000 -0.062
f5 0.286 0.522 0.395 -0.062 1.000

at the tables above we see the factor-items loadings and factors correlations

we need to know if there are any significant cross loading of any of the items

load<-fit$loadings%>%matrix(ncol = 5,dimnames = list(c(names(big[,-c(1,2)])),paste0("F",1:5)))%>%round(digits = 3)

load%>%apply(MARGIN = 2,FUN = function(x){
ifelse(test = x>=.3,yes = x,no = paste("-"))
})%>%matrix(ncol = 5,dimnames =list(c(names(big[,-c(1,2)])),paste0("F",1:5)))%>%kable(format = "markdown",digits = 3)
F1 F2 F3 F4 F5
E1 0.659 - - - -
E2 0.57 - - - -
E3 0.684 - - - -
E4 0.501 - - - -
E6 0.588 - - - -
E7 0.622 - - - -
N1 - - - 0.554 -
N2 - - - 0.591 -
N3 - - - 0.548 -
N5 - - - 0.735 -
N8 - - - 0.625 -
N9 - - - 0.461 -
A1 - - 0.547 - -
A2 - - 0.611 - -
A3 - - 0.714 - -
A4 - - 0.656 - -
A5 - - 0.587 - -
A6 - - 0.524 - -
O2 - - - - 0.73
O3 - - - - 0.415
O4 - - - - 0.643
O5 - - - - 0.652
O6 - - - - 0.405
O8 0.318 - - - -
C3 - 0.534 - - -
C4 - 0.389 - - -
C5 - 0.531 - - -
C6 - 0.86 - - -
C7 - 0.75 - - -
C8 - 0.456 - - -

in the loading detection table we see that item O8 which is supposed to load on to factor 5 , loads on factor 1

here i feel free to delete this item especially as we have another 5 items in its factor

big<-big%>%select(-O8)

and then run EFA again

fit<-fa(r = big[,-c(1,2)],nfactors = 5,rotate = "geominQ",fm = "ml") 
fa.diagram(fit,main = "diagram illustrating the EFA Model")

load<-fit$loadings%>%matrix(ncol = 5,dimnames = list(c(names(big[,-c(1,2)])),paste0("F",1:5)))%>%round(digits = 3)

load%>%apply(MARGIN = 2,FUN = function(x){
ifelse(test = x>=.3,yes = x,no = paste("-"))
})%>%matrix(ncol = 5,dimnames =list(c(names(big[,-c(1,2)])),paste0("F",1:5)))%>%kable(format = "markdown",digits = 3)
F1 F2 F3 F4 F5
E1 0.66 - - - -
E2 0.556 - - - -
E3 0.686 - - - -
E4 0.506 - - - -
E6 0.584 - - - -
E7 0.617 - - - -
N1 - - - 0.551 -
N2 - - - 0.595 -
N3 - - - 0.551 -
N5 - - - 0.733 -
N8 - - - 0.624 -
N9 - - - 0.462 -
A1 - - 0.542 - -
A2 - - 0.609 - -
A3 - - 0.708 - -
A4 - - 0.659 - -
A5 - - 0.593 - -
A6 - - 0.528 - -
O2 - - - - 0.743
O3 - - - - 0.413
O4 - - - - 0.631
O5 - - - - 0.638
O6 - - - - 0.399
C3 - 0.538 - - -
C4 - 0.387 - - -
C5 - 0.532 - - -
C6 - 0.865 - - -
C7 - 0.75 - - -
C8 - 0.454 - - -

Now it is awesome , we have here a great factors structure

So, lets test the reliability of each dimension using alpha

F1<-big%>%select(E1,E2,E3,E4,E6,E7)
F2<-big%>%select(N1,N2,N3,N5,N8,N9)
F3<-big%>%select(A1,A2,A3,A4,A5,A6)
F4<-big%>%select(O2,O3,O4,O5,O6)
F5<-big%>%select(C3,C4,C5,C6,C7,C8)

dimenstions<-list(F1,F2,F3,F4,F5)

alphas<-data.frame(test=alpha(check.keys = T,big%>%select(-c(Age,Sex)))$total[1],
                   F1=alpha(F1)$total[1],
                   F2=alpha(F2)$total[1],
                   F3=alpha(F3)$total[1],
                   F4=alpha(F4)$total[1],
                   F5=alpha(F5)$total[1])

names(alphas)<-c("All test",paste("F",1:5))
alphas%>%kable(format = "markdown",digits = 2) # table contain row alpha for the all items and every factor
All test F 1 F 2 F 3 F 4 F 5
0.86 0.79 0.78 0.8 0.75 0.81

here the alpha values of each factor is roughly good , so we can claim here that the dimensions is reliable

After finishing the EFA lets start in CFA and Confirming the structure of the model

First of all we have to specify the model

bigmodel<-"
f1=~ E1+E2+E3+E4+E6+E7
f2=~ N1+N2+N3+N5+N8+N9
f3=~ A1+A2+A3+A4+A5+A6
f4=~ O2+O3+O4+O5+O6
f5=~ C3+C4+C5+C6+C7+C8
"

After specifying the model we will use cfa() function to run the model

bigfit<-cfa(model = bigmodel,data = big%>%select(-c(Age,Sex)))

summary(bigfit,standardized=T,fit.measures=T)
## lavaan 0.6-3 ended normally after 54 iterations
## 
##   Optimization method                           NLMINB
##   Number of free parameters                         68
## 
##   Number of observations                           225
## 
##   Estimator                                         ML
##   Model Fit Test Statistic                     632.465
##   Degrees of freedom                               367
##   P-value (Chi-square)                           0.000
## 
## Model test baseline model:
## 
##   Minimum Function Test Statistic             2448.865
##   Degrees of freedom                               406
##   P-value                                        0.000
## 
## User model versus baseline model:
## 
##   Comparative Fit Index (CFI)                    0.870
##   Tucker-Lewis Index (TLI)                       0.856
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)              -7705.204
##   Loglikelihood unrestricted model (H1)      -7388.972
## 
##   Number of free parameters                         68
##   Akaike (AIC)                               15546.409
##   Bayesian (BIC)                             15778.703
##   Sample-size adjusted Bayesian (BIC)        15563.198
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.057
##   90 Percent Confidence Interval          0.049  0.064
##   P-value RMSEA <= 0.05                          0.071
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.068
## 
## Parameter Estimates:
## 
##   Information                                 Expected
##   Information saturated (h1) model          Structured
##   Standard Errors                             Standard
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   f1 =~                                                                 
##     E1                1.000                               0.622    0.688
##     E2                0.950    0.128    7.435    0.000    0.590    0.577
##     E3                1.184    0.129    9.188    0.000    0.736    0.749
##     E4                0.789    0.116    6.810    0.000    0.490    0.523
##     E6                0.888    0.116    7.647    0.000    0.552    0.595
##     E7                0.887    0.111    7.956    0.000    0.551    0.623
##   f2 =~                                                                 
##     N1                1.000                               0.542    0.541
##     N2                1.077    0.155    6.930    0.000    0.584    0.683
##     N3                1.153    0.161    7.159    0.000    0.625    0.731
##     N5                1.055    0.157    6.728    0.000    0.572    0.647
##     N8                0.935    0.162    5.755    0.000    0.507    0.507
##     N9                1.067    0.168    6.350    0.000    0.578    0.588
##   f3 =~                                                                 
##     A1                1.000                               0.462    0.564
##     A2                1.125    0.183    6.138    0.000    0.519    0.521
##     A3                1.187    0.165    7.175    0.000    0.548    0.655
##     A4                0.972    0.136    7.160    0.000    0.449    0.653
##     A5                1.200    0.154    7.782    0.000    0.554    0.757
##     A6                1.203    0.165    7.271    0.000    0.555    0.670
##   f4 =~                                                                 
##     O2                1.000                               0.631    0.683
##     O3                0.759    0.124    6.124    0.000    0.478    0.475
##     O4                1.120    0.130    8.629    0.000    0.706    0.718
##     O5                0.986    0.114    8.627    0.000    0.622    0.717
##     O6                0.782    0.117    6.680    0.000    0.493    0.523
##   f5 =~                                                                 
##     C3                1.000                               0.587    0.610
##     C4                0.908    0.128    7.107    0.000    0.533    0.579
##     C5                1.054    0.132    7.980    0.000    0.619    0.676
##     C6                1.168    0.140    8.375    0.000    0.686    0.725
##     C7                1.167    0.133    8.787    0.000    0.686    0.784
##     C8                0.826    0.122    6.752    0.000    0.485    0.543
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   f1 ~~                                                                 
##     f2               -0.153    0.036   -4.246    0.000   -0.454   -0.454
##     f3                0.090    0.027    3.365    0.001    0.315    0.315
##     f4                0.115    0.036    3.215    0.001    0.293    0.293
##     f5                0.107    0.033    3.248    0.001    0.292    0.292
##   f2 ~~                                                                 
##     f3                0.016    0.021    0.762    0.446    0.063    0.063
##     f4               -0.047    0.030   -1.593    0.111   -0.138   -0.138
##     f5               -0.060    0.028   -2.163    0.031   -0.188   -0.188
##   f3 ~~                                                                 
##     f4                0.129    0.031    4.234    0.000    0.444    0.444
##     f5                0.151    0.032    4.749    0.000    0.555    0.555
##   f4 ~~                                                                 
##     f5                0.218    0.042    5.160    0.000    0.589    0.589
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .E1                0.430    0.051    8.487    0.000    0.430    0.527
##    .E2                0.700    0.074    9.445    0.000    0.700    0.668
##    .E3                0.424    0.056    7.597    0.000    0.424    0.439
##    .E4                0.639    0.066    9.732    0.000    0.639    0.727
##    .E6                0.555    0.060    9.325    0.000    0.555    0.646
##    .E7                0.479    0.053    9.120    0.000    0.479    0.612
##    .N1                0.709    0.074    9.576    0.000    0.709    0.707
##    .N2                0.389    0.046    8.400    0.000    0.389    0.533
##    .N3                0.341    0.044    7.721    0.000    0.341    0.466
##    .N5                0.453    0.051    8.797    0.000    0.453    0.581
##    .N8                0.743    0.076    9.749    0.000    0.743    0.743
##    .N9                0.634    0.068    9.290    0.000    0.634    0.655
##    .A1                0.456    0.047    9.610    0.000    0.456    0.682
##    .A2                0.723    0.074    9.813    0.000    0.723    0.728
##    .A3                0.399    0.044    8.991    0.000    0.399    0.571
##    .A4                0.271    0.030    9.010    0.000    0.271    0.574
##    .A5                0.229    0.030    7.715    0.000    0.229    0.427
##    .A6                0.379    0.043    8.859    0.000    0.379    0.552
##    .O2                0.456    0.055    8.316    0.000    0.456    0.534
##    .O3                0.785    0.080    9.856    0.000    0.785    0.774
##    .O4                0.470    0.060    7.810    0.000    0.470    0.485
##    .O5                0.365    0.047    7.814    0.000    0.365    0.485
##    .O6                0.645    0.067    9.632    0.000    0.645    0.726
##    .C3                0.581    0.061    9.497    0.000    0.581    0.627
##    .C4                0.564    0.058    9.666    0.000    0.564    0.665
##    .C5                0.455    0.050    9.026    0.000    0.455    0.543
##    .C6                0.425    0.050    8.512    0.000    0.425    0.474
##    .C7                0.295    0.039    7.601    0.000    0.295    0.386
##    .C8                0.564    0.057    9.830    0.000    0.564    0.705
##     f1                0.386    0.072    5.357    0.000    1.000    1.000
##     f2                0.294    0.074    3.968    0.000    1.000    1.000
##     f3                0.213    0.050    4.232    0.000    1.000    1.000
##     f4                0.398    0.076    5.228    0.000    1.000    1.000
##     f5                0.345    0.073    4.711    0.000    1.000    1.000
semPaths(bigfit,whatLabels = "std",layout = "tree")

The number of DF in our model is 406 and the number of parameters estimated are 73 so, the remaining df are 367 and we have an over identified model

The following is the table of all parameters estimated

parameterEstimates(bigfit,standardized = T)%>%kable(digits = 2,format = "markdown")
lhs op rhs est se z pvalue ci.lower ci.upper std.lv std.all std.nox
f1 =~ E1 1.00 0.00 NA NA 1.00 1.00 0.62 0.69 0.69
f1 =~ E2 0.95 0.13 7.44 0.00 0.70 1.20 0.59 0.58 0.58
f1 =~ E3 1.18 0.13 9.19 0.00 0.93 1.44 0.74 0.75 0.75
f1 =~ E4 0.79 0.12 6.81 0.00 0.56 1.02 0.49 0.52 0.52
f1 =~ E6 0.89 0.12 7.65 0.00 0.66 1.12 0.55 0.60 0.60
f1 =~ E7 0.89 0.11 7.96 0.00 0.67 1.11 0.55 0.62 0.62
f2 =~ N1 1.00 0.00 NA NA 1.00 1.00 0.54 0.54 0.54
f2 =~ N2 1.08 0.16 6.93 0.00 0.77 1.38 0.58 0.68 0.68
f2 =~ N3 1.15 0.16 7.16 0.00 0.84 1.47 0.63 0.73 0.73
f2 =~ N5 1.05 0.16 6.73 0.00 0.75 1.36 0.57 0.65 0.65
f2 =~ N8 0.94 0.16 5.75 0.00 0.62 1.25 0.51 0.51 0.51
f2 =~ N9 1.07 0.17 6.35 0.00 0.74 1.40 0.58 0.59 0.59
f3 =~ A1 1.00 0.00 NA NA 1.00 1.00 0.46 0.56 0.56
f3 =~ A2 1.12 0.18 6.14 0.00 0.77 1.48 0.52 0.52 0.52
f3 =~ A3 1.19 0.17 7.17 0.00 0.86 1.51 0.55 0.66 0.66
f3 =~ A4 0.97 0.14 7.16 0.00 0.71 1.24 0.45 0.65 0.65
f3 =~ A5 1.20 0.15 7.78 0.00 0.90 1.50 0.55 0.76 0.76
f3 =~ A6 1.20 0.17 7.27 0.00 0.88 1.53 0.56 0.67 0.67
f4 =~ O2 1.00 0.00 NA NA 1.00 1.00 0.63 0.68 0.68
f4 =~ O3 0.76 0.12 6.12 0.00 0.52 1.00 0.48 0.48 0.48
f4 =~ O4 1.12 0.13 8.63 0.00 0.87 1.37 0.71 0.72 0.72
f4 =~ O5 0.99 0.11 8.63 0.00 0.76 1.21 0.62 0.72 0.72
f4 =~ O6 0.78 0.12 6.68 0.00 0.55 1.01 0.49 0.52 0.52
f5 =~ C3 1.00 0.00 NA NA 1.00 1.00 0.59 0.61 0.61
f5 =~ C4 0.91 0.13 7.11 0.00 0.66 1.16 0.53 0.58 0.58
f5 =~ C5 1.05 0.13 7.98 0.00 0.79 1.31 0.62 0.68 0.68
f5 =~ C6 1.17 0.14 8.38 0.00 0.90 1.44 0.69 0.73 0.73
f5 =~ C7 1.17 0.13 8.79 0.00 0.91 1.43 0.69 0.78 0.78
f5 =~ C8 0.83 0.12 6.75 0.00 0.59 1.07 0.49 0.54 0.54
E1 ~~ E1 0.43 0.05 8.49 0.00 0.33 0.53 0.43 0.53 0.53
E2 ~~ E2 0.70 0.07 9.44 0.00 0.55 0.85 0.70 0.67 0.67
E3 ~~ E3 0.42 0.06 7.60 0.00 0.31 0.53 0.42 0.44 0.44
E4 ~~ E4 0.64 0.07 9.73 0.00 0.51 0.77 0.64 0.73 0.73
E6 ~~ E6 0.56 0.06 9.32 0.00 0.44 0.67 0.56 0.65 0.65
E7 ~~ E7 0.48 0.05 9.12 0.00 0.38 0.58 0.48 0.61 0.61
N1 ~~ N1 0.71 0.07 9.58 0.00 0.56 0.85 0.71 0.71 0.71
N2 ~~ N2 0.39 0.05 8.40 0.00 0.30 0.48 0.39 0.53 0.53
N3 ~~ N3 0.34 0.04 7.72 0.00 0.25 0.43 0.34 0.47 0.47
N5 ~~ N5 0.45 0.05 8.80 0.00 0.35 0.55 0.45 0.58 0.58
N8 ~~ N8 0.74 0.08 9.75 0.00 0.59 0.89 0.74 0.74 0.74
N9 ~~ N9 0.63 0.07 9.29 0.00 0.50 0.77 0.63 0.65 0.65
A1 ~~ A1 0.46 0.05 9.61 0.00 0.36 0.55 0.46 0.68 0.68
A2 ~~ A2 0.72 0.07 9.81 0.00 0.58 0.87 0.72 0.73 0.73
A3 ~~ A3 0.40 0.04 8.99 0.00 0.31 0.49 0.40 0.57 0.57
A4 ~~ A4 0.27 0.03 9.01 0.00 0.21 0.33 0.27 0.57 0.57
A5 ~~ A5 0.23 0.03 7.72 0.00 0.17 0.29 0.23 0.43 0.43
A6 ~~ A6 0.38 0.04 8.86 0.00 0.30 0.46 0.38 0.55 0.55
O2 ~~ O2 0.46 0.05 8.32 0.00 0.35 0.56 0.46 0.53 0.53
O3 ~~ O3 0.78 0.08 9.86 0.00 0.63 0.94 0.78 0.77 0.77
O4 ~~ O4 0.47 0.06 7.81 0.00 0.35 0.59 0.47 0.48 0.48
O5 ~~ O5 0.36 0.05 7.81 0.00 0.27 0.46 0.36 0.49 0.49
O6 ~~ O6 0.64 0.07 9.63 0.00 0.51 0.78 0.64 0.73 0.73
C3 ~~ C3 0.58 0.06 9.50 0.00 0.46 0.70 0.58 0.63 0.63
C4 ~~ C4 0.56 0.06 9.67 0.00 0.45 0.68 0.56 0.66 0.66
C5 ~~ C5 0.46 0.05 9.03 0.00 0.36 0.55 0.46 0.54 0.54
C6 ~~ C6 0.42 0.05 8.51 0.00 0.33 0.52 0.42 0.47 0.47
C7 ~~ C7 0.30 0.04 7.60 0.00 0.22 0.37 0.30 0.39 0.39
C8 ~~ C8 0.56 0.06 9.83 0.00 0.45 0.68 0.56 0.71 0.71
f1 ~~ f1 0.39 0.07 5.36 0.00 0.25 0.53 1.00 1.00 1.00
f2 ~~ f2 0.29 0.07 3.97 0.00 0.15 0.44 1.00 1.00 1.00
f3 ~~ f3 0.21 0.05 4.23 0.00 0.11 0.31 1.00 1.00 1.00
f4 ~~ f4 0.40 0.08 5.23 0.00 0.25 0.55 1.00 1.00 1.00
f5 ~~ f5 0.35 0.07 4.71 0.00 0.20 0.49 1.00 1.00 1.00
f1 ~~ f2 -0.15 0.04 -4.25 0.00 -0.22 -0.08 -0.45 -0.45 -0.45
f1 ~~ f3 0.09 0.03 3.37 0.00 0.04 0.14 0.31 0.31 0.31
f1 ~~ f4 0.11 0.04 3.22 0.00 0.04 0.18 0.29 0.29 0.29
f1 ~~ f5 0.11 0.03 3.25 0.00 0.04 0.17 0.29 0.29 0.29
f2 ~~ f3 0.02 0.02 0.76 0.45 -0.02 0.06 0.06 0.06 0.06
f2 ~~ f4 -0.05 0.03 -1.59 0.11 -0.11 0.01 -0.14 -0.14 -0.14
f2 ~~ f5 -0.06 0.03 -2.16 0.03 -0.11 -0.01 -0.19 -0.19 -0.19
f3 ~~ f4 0.13 0.03 4.23 0.00 0.07 0.19 0.44 0.44 0.44
f3 ~~ f5 0.15 0.03 4.75 0.00 0.09 0.21 0.56 0.56 0.56
f4 ~~ f5 0.22 0.04 5.16 0.00 0.14 0.30 0.59 0.59 0.59

All Loaings are so good and all of them are significant but we have an issue with the correlation between the factors which supposed to be low , but here is so high and significant

Now lets look to the measurement fit indecies table

c(fitmeasures(object = bigfit,fit.measures = c("chisq","df","cfi","tli","rmsea","rmsea.ci.upper","rmsea.ci.lower")))%>%round(digits = 3)%>%data.frame()%>%t()%>%kable(format = "markdown")
chisq df cfi tli rmsea rmsea.ci.upper rmsea.ci.lower
. 632.465 367 0.87 0.856 0.057 0.064 0.049

the model has a good measures as CFI is moderate as well as TLI

but RMSEA is very good with Excellent Interval

The only issue in the model is the high correlation of the factors

Now Lets try building the model by ESEM Methods and see the difference between it and traditional CFA

esemmodel<-vector()

for(i in 1:5){
esemmodel[i]<-paste0("f",i,"=~",paste0(c(load[,i]),"*",names(load[,1]),collapse = "+"))
}

esemmodel<-paste0(esemmodel,collapse = "\n") #Model Specification

esemfit<-cfa(model = esemmodel,data = big[,-c(1,2)]) #fitting the model

all.fit<-rbind(c(fitmeasures(object = bigfit,fit.measures = c("chisq","df","cfi","tli","rmsea","rmsea.ci.upper","rmsea.ci.lower")))%>%round(digits = 3)%>%data.frame()%>%t(),c(fitmeasures(object = esemfit,fit.measures = c("chisq","df","cfi","tli","rmsea","rmsea.ci.upper","rmsea.ci.lower")))%>%round(digits = 3)%>%data.frame()%>%t())%>%data.frame()

rownames(all.fit)<-c("CFA","ESEM")

all.fit%>%kable(format = "markdown")
chisq df cfi tli rmsea rmsea.ci.upper rmsea.ci.lower
CFA 632.465 367 0.870 0.856 0.057 0.064 0.049
ESEM 443.103 391 0.974 0.974 0.024 0.035 0.007

SEE !! The fit measures improved a lot in case of ESEM method

Now lets look at the correlation between the factors

data.frame(parameterestimates(object = esemfit,standardized = T))[180:189,c(1:3,11)]%>%kable(digits = 3,row.names = F,format = "markdown")
lhs op rhs std.all
f1 ~~ f2 0.159
f1 ~~ f3 0.151
f1 ~~ f4 -0.159
f1 ~~ f5 0.213
f2 ~~ f3 0.381
f2 ~~ f4 -0.149
f2 ~~ f5 0.435
f3 ~~ f4 0.113
f3 ~~ f5 0.296
f4 ~~ f5 -0.056

Here we can find the model match the theory as the factors are almost uncorrelated (Except f2~f3 , f2~f5 ) !!

Now I Think that it is time of exploring the measurement invariance using the two method

1- CFA Method

scalarfit<-cfa(model = bigmodel,data = big[,-c(1)],group = "Sex",group.equal = c("loadings","intercepts"))

measurementInvariance(model=bigmodel,data=big[,-c(1)],strict = T,group="Sex")
## 
## Measurement invariance models:
## 
## Model 1 : fit.configural
## Model 2 : fit.loadings
## Model 3 : fit.intercepts
## Model 4 : fit.residuals
## Model 5 : fit.means
## 
## Chi Square Difference Test
## 
##                 Df   AIC   BIC  Chisq Chisq diff Df diff Pr(>Chisq)   
## fit.configural 734 15650 16313 1122.2                                 
## fit.loadings   758 15629 16210 1148.9     26.773      24   0.315143   
## fit.intercepts 782 15629 16127 1196.8     47.853      24   0.002632 **
## fit.residuals  811 15615 16015 1241.3     44.491      29   0.032950 * 
## fit.means      816 15619 16001 1254.9     13.628       5   0.018154 * 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## 
## Fit measures:
## 
##                  cfi rmsea cfi.delta rmsea.delta
## fit.configural 0.823 0.069        NA          NA
## fit.loadings   0.822 0.068     0.001       0.001
## fit.intercepts 0.811 0.069     0.011       0.001
## fit.residuals  0.804 0.069     0.007       0.000
## fit.means      0.800 0.069     0.004       0.000

Here we see that we can’t prove the scalar invariance because of the difference between it and metric invariance in CFI >.01

So, we have to test the partial invariance using freeing a parameter one-by-one method

inter<-paste0(c(names(load[,1])),"~",1)

chi.diff<-list()

for(i in inter){
        test2<-cfa(model = bigmodel,
                   data = big[,-c(1)],
                   group = "Sex",
                   group.equal = c("loadings","intercepts"),
                   group.partial = i)
        chi.diff[[i]]<-c(i,fitmeasures(scalarfit,fit.measures = "chisq")-fitmeasures(test2,fit.measures = "chisq"))
}

chi.diff<-data.frame(chi.diff)%>%t()%>%data.frame()

names(chi.diff)<-c("intercept","chi-difference")

chi.diff<-chi.diff%>%mutate(`chi-difference`=as.character(`chi-difference`))%>%mutate(`chi-difference`=as.numeric(`chi-difference`))

chi.diff[order(chi.diff$`chi-difference`,decreasing = T),]%>%kable(digits = 3,format = "markdown",row.names = F,align = "c")
intercept chi-difference
O3~1 12.170
N9~1 5.109
N1~1 4.924
E2~1 4.508
E6~1 4.261
O5~1 3.991
C6~1 3.098
C8~1 2.629
O4~1 2.614
N3~1 2.201
O2~1 2.097
O6~1 1.665
A4~1 1.431
A5~1 1.412
N5~1 1.350
E7~1 0.935
A6~1 0.590
E3~1 0.336
C5~1 0.293
A3~1 0.269
N2~1 0.256
E1~1 0.242
C3~1 0.139
E4~1 0.063
C4~1 0.015
N8~1 0.013
A2~1 0.009
A1~1 0.006
C7~1 0.000

OK, the intercept of item O3 has the big change in chisq , so, lets let it free and test partial measurement invariance

measurementInvariance(model=bigmodel,data=big[,-c(1)],strict = T,group="Sex",group.partial = "O3~1")
## 
## Measurement invariance models:
## 
## Model 1 : fit.configural
## Model 2 : fit.loadings
## Model 3 : fit.intercepts
## Model 4 : fit.residuals
## Model 5 : fit.means
## 
## Chi Square Difference Test
## 
##                 Df   AIC   BIC  Chisq Chisq diff Df diff Pr(>Chisq)   
## fit.configural 734 15650 16313 1122.2                                 
## fit.loadings   758 15629 16210 1148.9     26.773      24   0.315143   
## fit.intercepts 781 15618 16121 1184.6     35.684      23   0.044423 * 
## fit.residuals  810 15605 16008 1229.1     44.460      29   0.033175 * 
## fit.means      815 15611 15997 1245.2     16.156       5   0.006412 **
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## 
## Fit measures:
## 
##                  cfi rmsea cfi.delta rmsea.delta
## fit.configural 0.823 0.069        NA          NA
## fit.loadings   0.822 0.068     0.001       0.001
## fit.intercepts 0.816 0.068     0.006       0.000
## fit.residuals  0.809 0.068     0.007       0.000
## fit.means      0.804 0.069     0.005       0.001

Congrats !! only O3 is the differential item functioning , and the measurement is partially invariant with Equal mean across groups using TRADITIONAL CFA method

2- ESEM Method

lets judge on the measurement invariance using this new method and see how it acts differently!!

measurementInvariance(model=esemmodel,data=big[,-1],strict = T,group="Sex")
## 
## Measurement invariance models:
## 
## Model 1 : fit.configural
## Model 2 : fit.loadings
## Model 3 : fit.intercepts
## Model 4 : fit.residuals
## Model 5 : fit.means
## 
## Chi Square Difference Test
## 
##                 Df   AIC   BIC   Chisq Chisq diff Df diff Pr(>Chisq)   
## fit.configural 782 15391 15890  959.13                                 
## fit.loadings   782 15391 15890  959.13      0.000       0              
## fit.intercepts 806 15388 15804 1003.84     44.701      24   0.006318 **
## fit.residuals  835 15375 15693 1049.42     45.582      29   0.025808 * 
## fit.means      840 15381 15681 1064.74     15.323       5   0.009067 **
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## 
## Fit measures:
## 
##                  cfi rmsea cfi.delta rmsea.delta
## fit.configural 0.919 0.045        NA          NA
## fit.loadings   0.919 0.045     0.000       0.000
## fit.intercepts 0.910 0.047     0.009       0.002
## fit.residuals  0.902 0.048     0.008       0.001
## fit.means      0.897 0.049     0.005       0.001

See !! The measurement invariance is perfect at all levels with difference in CFI <.01 in all models and also with better fit measures.

And here with ESEM we can stop at this point and say that there are a complete measure invariance in All Levels (Config. weak. strong. strict. means) of invariance measurement

Finally lets make conclusion about our results of the two methods

Comparison facet CFA ESEM
Model fit The fit measures in CFA was poor compared to ESEM , CFI(.87) The model here is very good with high CFI(0.974) and difference from CFA model is CFI > .01 and this is significant
Factors correlation The factor correlation here doesn’t match the theory as it is supposed to be uncorrelated The correlation here is more better since most of factors uncorrelated
measurement invariance The Model was good in proving the partial invarince (config , weak , strong , mean) A conclusion of complete measurement invariance with better fit measures