How to run EFA & CFA in R

Exploratory Factor Analysis (EFA) and Confirmatory Factor Analysis (CFA) are important techniques that are used extensively in psychometrics and the social sciences. Both EFA and CFA are crucial for understanding relationships between observed variables and underlying constructs. They aid in developing and validating measurement instruments and testing theories about the structure of psychological constructs.

EFA is used to identify the underlying structure of a set of observed variables without preconceived hypotheses. It helps researchers determine the number of latent factors that explain patterns of correlations among variables. EFA is valuable in generating hypotheses about underlying structures early in research.

CFA is used to test specific hypotheses about the underlying structure of observed variables. Researchers propose a theoretical model that specifies relationships between observed variables and latent factors. CFA tests whether data support the hypothesized model and assesses the model’s goodness-of-fit to the data.

In the code and video below I demonstrate the basics of conducting an EFA and CFA in R.


Subscribe to stay up to date on my latest videos, courses, and content



# Load required libraries
library(tidyverse)
library(psych)  # For EFA functions (although some in base R)
library(lavaan) # For CFA functions

# -------- Exploratory Factor Analysis (EFA) --------

# 1. Data suitability and assumptions
data(HolzingerSwineford1939)
HSdata<-select(HolzingerSwineford1939, x1:x9)

cortest.bartlett(R=cor(HSdata), n=301)  # Bartlett's test of sphericity (want p<.05)
KMO(HSdata)  # Kaiser-Meyer-Olkin measure of sampling adequacy (>0.6 ideally >0.8)

# 2. Determine the number of factors
fa.parallel(HSdata, fa="fa", fm="ml", show.legend=F)  # Parallel analysis

# 3. Extract factors (assuming parallel analysis suggests 3 factors)
#    promax rotation is oblique so factors can be correlated (vs varimax which is orthogonal)
efa.result <- factanal(HSdata, factors = 3, rotation = "promax") 
print(efa.result)  # View factor loadings
print(efa.result, cutoff=0.4)  # View factor loadings

# other rotation options using GPArotation package
library(GPArotation)
efa.result <- factanal(HSdata, factors = 3, rotation = "oblimin") 
print(efa.result)  # View factor loadings


# -------- Confirmatory Factor Analysis (CFA) --------

# 4. Define your CFA model (Example using lavaan syntax)

model <- 'visual  =~ x1 + x2 + x3
  textual =~ x4 + x5 + x6
  speed   =~ x7 + x8 + x9'

# 5. Fit the CFA model
cfa.result <- cfa(model, data = HSdata)  

# 6. Assessment of CFA fit
summary(cfa.result, fit.measures = TRUE)  # View fit indices (CFI, TLI, RMSEA, etc.)