SEM R lavaan:
Latent Interactions (Moderation) With Double Mean Centering
Arndt Regorz, Dipl. Kfm. & M.Sc. Psychology, 11/29/2022
(Note: When you click on this video you are using a service offered by YouTube.)
Here is the R code for the Youtube tutorial about latent interactions in lavaan:
library(lavaan)
library(semTools)
head(mydata)
# Testing model fit (without interaction)
# Measurement model (step 1)
test_model <- '
# loadings
iv =~ IV1 + IV2 + IV3
mod =~ MOD1 + MOD2 + MOD3
dv =~ DV1 + DV2 + DV3
'
test_fit <- cfa(test_model, data = mydata, estimator="MLM")
summary(test_fit, fit.measures = TRUE, standardized=TRUE)
mi <- modificationindices(test_fit)
mi[mi$mi>10,]
# Structural model (step 2; not necessary here because of saturated structural part)
test_model2 <- '
# loadings
iv =~ IV1 + IV2 + IV3
mod =~ MOD1 + MOD2 + MOD3
dv =~ DV1 + DV2 + DV3
# regression
dv ~ iv + mod
'
test_fit2 <- sem(test_model2, data = mydata, estimator="MLM")
summary(test_fit2, fit.measures = TRUE, standardized=TRUE)
mi <- modificationindices(test_fit)
mi[mi$mi>10,]
# Double Mean Centering
mydata_dmc <- indProd (mydata , var1 = c("IV1", "IV2", "IV3"),
var2 = c("MOD1", "MOD2", "MOD3"),
match = FALSE , meanC = TRUE ,
residualC = FALSE , doubleMC = TRUE)
head(mydata_dmc)
# Model estimation with latent interaction
int_model <- '
# Loadings
iv =~ IV1 + IV2 + IV3
mod =~ MOD1 + MOD2 + MOD3
dv =~ DV1 + DV2 + DV3
int =~ IV1.MOD1 + IV1.MOD2 + IV1.MOD3 + IV2.MOD1 + IV2.MOD2 +
IV2.MOD3 + IV3.MOD1 + IV3.MOD2 + IV3.MOD3
# Regression
dv ~ iv + mod + int
# Error covariances
IV1.MOD1 ~~ IV1.MOD2 + IV1.MOD3 + IV2.MOD1 + IV3.MOD1
IV1.MOD2 ~~ IV1.MOD3 + IV2.MOD2 + IV3.MOD2
IV1.MOD3 ~~ IV2.MOD3 + IV3.MOD3
IV2.MOD1 ~~ IV2.MOD2 + IV2.MOD3 + IV3.MOD1
IV2.MOD2 ~~ IV2.MOD3 + IV3.MOD2
IV2.MOD3 ~~ IV3.MOD3
IV3.MOD1 ~~ IV3.MOD2 + IV3.MOD3
IV3.MOD2 ~~ IV3.MOD3
'
int_fit <- sem(int_model, data = mydata_dmc, estimator="MLM")
summary(int_fit, fit.measures = TRUE, standardized=TRUE)
# Simple Slopes
probe <- probe2WayMC(int_fit, c("iv", "mod", "int"), "dv", "mod",
c(-sqrt(1.462),0, sqrt(1.462)))
probe
plotProbe(probe, c(-3,3))
# Double mean centering done manually
# Step 1: 1st mean centering of indicators for IV and MOD
attach(mydata2)
mydata2$IV1c <- scale(IV1, scale = FALSE)
mydata2$IV2c <- scale(IV2, scale = FALSE)
mydata2$IV3c <- scale(IV3, scale = FALSE)
mydata2$MOD1c <- scale(MOD1, scale = FALSE)
mydata2$MOD2c <- scale(MOD2, scale = FALSE)
mydata2$MOD3c <- scale(MOD3, scale = FALSE)
detach(mydata2)
# Step 2: Product terms
attach(mydata2)
mydata2$I1M1 <- IV1c * MOD1c
mydata2$I1M2 <- IV1c * MOD2c
mydata2$I1M3 <- IV1c * MOD3c
mydata2$I2M1 <- IV2c * MOD1c
mydata2$I2M2 <- IV2c * MOD2c
mydata2$I2M3 <- IV2c * MOD3c
mydata2$I3M1 <- IV3c * MOD1c
mydata2$I3M2 <- IV3c * MOD2c
mydata2$I3M3 <- IV3c * MOD3c
detach(mydata2)
# Step 3: 2nd mean centering (product terms)
attach(mydata2)
mydata2$I1M1c <- scale(I1M1, scale = FALSE)
mydata2$I1M2c <- scale(I1M2, scale = FALSE)
mydata2$I1M3c <- scale(I1M3, scale = FALSE)
mydata2$I2M1c <- scale(I2M1, scale = FALSE)
mydata2$I2M2c <- scale(I2M2, scale = FALSE)
mydata2$I2M3c <- scale(I2M3, scale = FALSE)
mydata2$I3M1c <- scale(I3M1, scale = FALSE)
mydata2$I3M2c <- scale(I3M2, scale = FALSE)
mydata2$I3M3c <- scale(I3M3, scale = FALSE)
detach(mydata2)
head(mydata2)