semPower for a CFA - R code

Here you can find the R code for a power analysis for a confirmatory factor analysis with the semPower package.

First, you will find the code for an a priori analysis (sample size planning), then the code for a post hoc analysis:

  1. A priori power
  2. Post hoc power

1. R code for an a priori power analysis

# Installing and Loading the Packages
install.packages("semPower") # once
install.packages("lavaan") # once
library(semPower) # each session
library(lavaan) # each session

# 1 A priori calculation full model

# Extracting the df from a lavaan model
cfa1 <- '
factor1 =~ x1 + x2 + x3
factor2 =~ x4 + x5 + x6
factor3 =~ x7 + x8 + x9

factor1 ~~ factor2
factor1 ~~ factor3
factor2 ~~ factor3 '

semPower.getDf(cfa1)

# RMSEA > .08
cfa_full <- semPower.aPriori(0.08,
'RMSEA',
alpha = .05,
power = .80,
df = 24)
summary(cfa_full)

# 2 Specific Effects

# 2.1 Factor correlation different from zero (F1-F3)

Phi1 <- matrix(c(
c(1.00, 0.20, 0.30),
c(0.20, 1.00, 0.10),
c(0.30, 0.10, 1.00)
),
ncol = 3,
byrow = TRUE)

# 2.1.1 All loadings equal for a factor

cfa_corr1 <- semPower.powerCFA(type = 'a-priori',
Phi = Phi1,
nullWhich = c(1, 3),
nIndicator = c(3, 3, 3),
loadM = c(.65, .60, .70),
alpha = .05,
power = .80)
summary(cfa_corr1)

# 2.1.2 Specific loadings

cfa_corr2 <- semPower.powerCFA(type = 'a-priori',
Phi = Phi1,
nullWhich = c(1, 3),
loadings = list(c(.60, .65, .70),
c(.50, .60, .70),
c(.65, .70, .75)),
alpha = .05,
power = .80)
summary(cfa_corr2)

# 2.1.3 Checking if model definition is correct

p_calc <- cfa_corr1

h1_model <- lavaan::sem(p_calc$modelH1,
sample.cov = p_calc$Sigma,
sample.nobs = p_calc$requiredN,
sample.cov.rescale = F)

h0_model <- lavaan::sem(p_calc$modelH0,
sample.cov = p_calc$Sigma,
sample.nobs = p_calc$requiredN,
sample.cov.rescale = F)

summary(h1_model)
summary(h0_model)

# 2.2 Two factor correlations different from each other
# (F1-F3 vs. F2-F3)

cfa_corr_diff <- semPower.powerCFA(type = 'a-priori',
Phi = Phi1,
nullEffect = 'corX = corZ',
nullWhich = list(c(1, 3), c(2, 3)),
nIndicator = c(3, 3, 3),
loadM = c(.65, .60, .70),
alpha = .05,
power = .80)
summary(cfa_corr_diff)

# 2.3 Loading different from zero
# (loading item 4-f2)

Lambda1 <- matrix(c(
c(.60, 0, 0), # item1-f1, item1-f2, item1-f3
c(.65, 0, 0),
c(.70, 0, 0),
c(0, .50, 0),
c(0, .60, 0),
c(0, .70, 0),
c(0, 0, .65),
c(0, 0, .70),
c(0, 0, .75)
),
ncol = 3,
byrow = TRUE)

cfa_load <- semPower.powerCFA(type = 'a-priori',
Phi = Phi1,
nullEffect = 'loading = 0',
nullWhich = c(4,2),
Lambda = Lambda1,
alpha = .05,
power = .80)
summary(cfa_load)

2. R code for a post hoc power analysis

# Installing and Loading the Packages
install.packages("semPower") # once
install.packages("lavaan") # once
library(semPower) # each session
library(lavaan) # each session

# 1 Full Model

# Post hoc calculation full model

cfa_full <- semPower.postHoc(0.055,
'RMSEA',
alpha = .05,
N = 200,
df = 24)
summary(cfa_full)

# 2 Specific Effects

# 2.1 Factor correlation

Phi1 <- matrix(c(
c(1.00, 0.22, 0.25),
c(0.22, 1.00, 0.13),
c(0.25, 0.13, 1.00)
),
ncol = 3,
byrow = TRUE)

cfa_corr <- semPower.powerCFA(type = 'post-hoc',
Phi = Phi1,
nullEffect = 'cor = 0',
nullWhich = c(1, 3),
loadings = list(c(.61, .62, .70),
c(.52, .62, .72),
c(.66, .71, .75)),
alpha = .05,
N = 200)
summary(cfa_corr)

# 2.2 Two factor correlations different from each other

cfa_corr_diff <- semPower.powerCFA(type = 'post-hoc',
Phi = Phi1,
nullEffect = 'corX = corZ',
nullWhich = list(c(1, 3), c(2, 3)),
loadings = list(c(.61, .62, .70),
c(.52, .62, .72),
c(.66, .71, .75)),
alpha = .05,
N = 200) summary(cfa_corr_diff)

# 2.3 Loading different from zero

Lambda1 <- matrix(c(
c(.61, 0, 0),
c(.62, 0, 0),
c(.70, 0, 0),
c(0, .52, 0),
c(0, .62, 0),
c(0, .72, 0),
c(0, 0, .66),
c(0, 0, .71),
c(0, 0, .75)
),
ncol = 3,
byrow = TRUE)

cfa_load <- semPower.powerCFA(type = 'post-hoc',
Phi = Phi1,
nullEffect = 'loading = 0',
nullWhich = c(4,2),
Lambda = Lambda1,
alpha = .05,
N = 200)
summary(cfa_load)