This article attempts to reproduce several different possible
lavaan
models. We start with the source itself: The lavaan
project at https://lavaan.ugent.be. Let’s start by loading both
packages.
library(lavaan)
library(lavaanExtra)
Source: https://lavaan.ugent.be/tutorial/syntax1.html
lavaan
:
<- ' # regressions
myModel y1 + y2 ~ f1 + f2 + x1 + x2
f1 ~ f2 + f3
f2 ~ f3 + x1 + x2
# latent variable definitions
f1 =~ y1 + y2 + y3
f2 =~ y4 + y5 + y6
f3 =~ y7 + y8 + y9 + y10
# variances and covariances
y1 ~~ y1
y1 ~~ y2
f1 ~~ f2
# intercepts
y1 ~ 1
f1 ~ 1
'
lavaanExtra
:
<- list(y1 = c("f1", "f2", "x1", "x2"),
reg y2 = c("f1", "f2", "x1", "x2"),
f1 = c("f2", "f3"),
f2 = c("f3", "x1", "x2"))
<- list(f1 = paste0("y", 1:3),
lat f2 = paste0("y", 4:6),
f3 = paste0("y", 7:10))
<- list(y1 = "y1",
cov y1 = "y2",
f1 = "f2")
<- c("y1", "f1")
int <- write_lavaan(regression = reg, latent = lat, covariance = cov,
myModel intercept = int)
cat(myModel)
## ##################################################
## # [---------------Latent variables---------------]
##
## f1 =~ y1 + y2 + y3
## f2 =~ y4 + y5 + y6
## f3 =~ y7 + y8 + y9 + y10
##
## ##################################################
## # [---------Regressions (Direct effects)---------]
##
## y1 ~ f1 + f2 + x1 + x2
## y2 ~ f1 + f2 + x1 + x2
## f1 ~ f2 + f3
## f2 ~ f3 + x1 + x2
##
## ##################################################
## # [------------------Covariances-----------------]
##
## y1 ~~ y1
## y1 ~~ y2
## f1 ~~ f2
##
## ##################################################
## # [------------------Intercepts------------------]
##
## y1 ~ 1
## f1 ~ 1
Source: https://lavaan.ugent.be/tutorial/cfa.html
lavaan
:
<- ' visual =~ x1 + x2 + x3
HS.model textual =~ x4 + x5 + x6
speed =~ x7 + x8 + x9 '
lavaanExtra
:
<- list(visual = paste0("x", 1:3),
lat textual = paste0("x", 4:6),
speed = paste0("x", 7:9))
<- write_lavaan(latent = lat)
myModel cat(myModel)
## ##################################################
## # [---------------Latent variables---------------]
##
## visual =~ x1 + x2 + x3
## textual =~ x4 + x5 + x6
## speed =~ x7 + x8 + x9
Source: https://lavaan.ugent.be/tutorial/sem.html
lavaan
:
<- '
model # measurement model
ind60 =~ x1 + x2 + x3
dem60 =~ y1 + y2 + y3 + y4
dem65 =~ y5 + y6 + y7 + y8
# regressions
dem60 ~ ind60
dem65 ~ ind60 + dem60
# residual correlations
y1 ~~ y5
y2 ~~ y4 + y6
y3 ~~ y7
y4 ~~ y8
y6 ~~ y8
'
lavaanExtra
:
<- list(ind60 = paste0("x", 1:3),
lat dem60 = paste0("y", 1:4),
dem65 = paste0("y", 5:8))
<- list(dem60 = "ind60",
reg dem65 = c("ind60", "dem60"))
<- list(y1 = "y5",
cov y2 = c("y4", "y6"),
y3 = "y7",
y4 = "y8",
y6 = "y8")
<- write_lavaan(latent = lat, regression = reg, covariance = cov)
model cat(model)
## ##################################################
## # [---------------Latent variables---------------]
##
## ind60 =~ x1 + x2 + x3
## dem60 =~ y1 + y2 + y3 + y4
## dem65 =~ y5 + y6 + y7 + y8
##
## ##################################################
## # [---------Regressions (Direct effects)---------]
##
## dem60 ~ ind60
## dem65 ~ ind60 + dem60
##
## ##################################################
## # [------------------Covariances-----------------]
##
## y1 ~~ y5
## y2 ~~ y4 + y6
## y3 ~~ y7
## y4 ~~ y8
## y6 ~~ y8
Source: https://lavaan.ugent.be/tutorial/syntax2.html
lavaan
:
<- '
model # three-factor model
visual =~ x1 + x2 + x3
textual =~ x4 + x5 + x6
speed =~ NA*x7 + x8 + x9
# orthogonal factors
visual ~~ 0*speed
textual ~~ 0*speed
# fix variance of speed factor
speed ~~ 1*speed
'
lavaanExtra
:
<- list(visual = paste0("x", 1:3),
lat textual = paste0("x", 4:6),
speed = c("NA*x7", "x8", "x9"))
<- list(visual = "0*speed",
cov textual = "0*speed",
speed = "1*speed")
<- write_lavaan(latent = lat, covariance = cov)
model cat(model)
## ##################################################
## # [---------------Latent variables---------------]
##
## visual =~ x1 + x2 + x3
## textual =~ x4 + x5 + x6
## speed =~ NA*x7 + x8 + x9
##
## ##################################################
## # [------------------Covariances-----------------]
##
## visual ~~ 0*speed
## textual ~~ 0*speed
## speed ~~ 1*speed
lavaan
:
<- '
model visual =~ x1 + start(0.8)*x2 + start(1.2)*x3
textual =~ x4 + start(0.5)*x5 + start(1.0)*x6
speed =~ x7 + start(0.7)*x8 + start(1.8)*x9
'
lavaanExtra
:
<- list(visual = c("x1", "start(0.8)*x2", "start(1.2)*x3"),
lat textual = c("x4", "start(0.5)*x5", "start(1.0)*x6"),
speed = c("x7", "start(0.7)*x8", "start(1.8)*x9"))
<- write_lavaan(latent = lat)
model cat(model)
## ##################################################
## # [---------------Latent variables---------------]
##
## visual =~ x1 + start(0.8)*x2 + start(1.2)*x3
## textual =~ x4 + start(0.5)*x5 + start(1.0)*x6
## speed =~ x7 + start(0.7)*x8 + start(1.8)*x9
lavaan
:
<- '
model f =~ y1 + y2 + myLabel*y3 + start(0.5)*y3 + y4
'
lavaanExtra
:
<- list(f = c("y1", "y2", "myLabel*y3", "start(0.5)*y3", "y4"))
lat <- write_lavaan(latent = lat)
model cat(model)
## ##################################################
## # [---------------Latent variables---------------]
##
## f =~ y1 + y2 + myLabel*y3 + start(0.5)*y3 + y4
lavaan
:
<- '
model visual =~ x1 + v2*x2 + v2*x3
textual =~ x4 + x5 + x6
speed =~ x7 + x8 + x9
'
lavaanExtra
:
<- list(visual = c("x1", "v2*x2", "v2*x3"),
lat textual = paste0("x", 4:6),
speed = paste0("x", 7:9))
<- write_lavaan(latent = lat)
model cat(model)
## ##################################################
## # [---------------Latent variables---------------]
##
## visual =~ x1 + v2*x2 + v2*x3
## textual =~ x4 + x5 + x6
## speed =~ x7 + x8 + x9
lavaan
:
<- '
model visual =~ x1 + x2 + equal("visual=~x2")*x3
textual =~ x4 + x5 + x6
speed =~ x7 + x8 + x9
'
sem(model, data = HolzingerSwineford1939)
## lavaan 0.6-12 ended normally after 36 iterations
##
## Estimator ML
## Optimization method NLMINB
## Number of model parameters 21
## Number of equality constraints 1
##
## Number of observations 301
##
## Model Test User Model:
##
## Test statistic 87.971
## Degrees of freedom 25
## P-value (Chi-square) 0.000
lavaanExtra
:
<- list(visual = c("x1", "x2", "equal('visual=~x2')*x3"),
lat textual = paste0("x", 4:6),
speed = paste0("x", 7:9))
<- write_lavaan(latent = lat)
model cat(model)
## ##################################################
## # [---------------Latent variables---------------]
##
## visual =~ x1 + x2 + equal('visual=~x2')*x3
## textual =~ x4 + x5 + x6
## speed =~ x7 + x8 + x9
sem(model, data = HolzingerSwineford1939)
## lavaan 0.6-12 ended normally after 36 iterations
##
## Estimator ML
## Optimization method NLMINB
## Number of model parameters 21
## Number of equality constraints 1
##
## Number of observations 301
##
## Model Test User Model:
##
## Test statistic 87.971
## Degrees of freedom 25
## P-value (Chi-square) 0.000
lavaan
:
<- ' # model with labeled parameters
model.constr y ~ b1*x1 + b2*x2 + b3*x3
# constraints
b1 == (b2 + b3)^2
b1 > exp(b2 + b3) '
lavaanExtra
:
<- list(y = c("b1*x1", "b2*x2", "b3*x3"))
reg <- list(b1 = "(b2 + b3)^2")
cstr1 <- list(b1 = "exp(b2 + b3)")
cstr2 <- write_lavaan(regression = reg, constraint.equal = cstr1,
model constraint.larger = cstr2)
cat(model)
## ##################################################
## # [---------Regressions (Direct effects)---------]
##
## y ~ b1*x1 + b2*x2 + b3*x3
##
## ##################################################
## # [-----------------Constraints------------------]
##
## b1 == (b2 + b3)^2
## b1 > exp(b2 + b3)
Source: https://lavaan.ugent.be/tutorial/mediation.html
lavaan
:
<- ' # direct effect
model Y ~ c*X
# mediator
M ~ a*X
Y ~ b*M
# indirect effect (a*b)
ab := a*b
# total effect
total := c + (a*b)
'
lavaanExtra
:
<- list(Y = "c*X",
mediation M = "a*X",
Y = "b*M")
<- list(ab = "a*b",
indirect total = "c + (a*b)")
<- write_lavaan(mediation, indirect = indirect)
model cat(model)
## ##################################################
## # [-----------Mediations (named paths)-----------]
##
## Y ~ c*X
## M ~ a*X
## Y ~ b*M
##
## ##################################################
## # [--------Mediations (indirect effects)---------]
##
## ab := a*b
## total := c + (a*b)
Source: https://lavaan.ugent.be/tutorial/multilevel.html
lavaan
:
<- '
model level: 1
fw =~ y1 + y2 + y3
fw ~ x1 + x2 + x3
level: 2
fb =~ y1 + y2 + y3
fb ~ w1 + w2
'
lavaanExtra
:
<-
cus "level: 1
fw =~ y1 + y2 + y3
fw ~ x1 + x2 + x3
level: 2
fb =~ y1 + y2 + y3
fb ~ w1 + w2
"
<- write_lavaan(custom = cus)
model cat(model)
## ##################################################
## # [------------Custom Specifications-------------]
##
## level: 1
## fw =~ y1 + y2 + y3
## fw ~ x1 + x2 + x3
## level: 2
## fb =~ y1 + y2 + y3
## fb ~ w1 + w2
lavaan
:
<- '
model_mediation # Measurement model
SUP_Parents =~ sup_parents_p1 + sup_parents_p2 + sup_parents_p3
SUP_Friends =~ sup_friends_p1 + sup_friends_p2 + sup_friends_p3
SE_Academic =~ se_acad_p1 + se_acad_p2 + se_acad_p3
SE_Social =~ se_social_p1 + se_social_p2 + se_social_p3
LS =~ ls_p1 + ls_p2 + ls_p3
# Structural model
# Regressions
SE_Academic ~ b1*SUP_Parents + b3*SUP_Friends
SE_Social ~ b2*SUP_Parents + b4*SUP_Friends
LS ~ b5*SUP_Parents + b6*SUP_Friends + b7*SE_Academic + b8*SE_Social
# Residual covariances
SE_Academic ~~ SE_Social
# Indirect effects
b1b7 := b1*b7
b2b8 := b2*b8
totalind_eltern := b1*b7 + b2*b8
b3b7 := b3*b7
b4b8 := b4*b8
totalind_freunde := b3*b7 + b4*b8
# Total effects
total_eltern := b1*b7 + b2*b8 + b5
total_freunde := b3*b7 + b4*b8 + b6
'
lavaanExtra
:
<- c("sup_parents", "sup_friends", "se_acad", "se_social", "ls")
x <- lapply(x, paste0, "_p", 1:3)
y <- setNames(y, x)
y <- list(SUP_Parents = y$sup_parents,
lat SUP_Friends = y$sup_friends,
SE_Academic = y$se_acad,
SE_Social = y$se_social,
LS = y$ls)
<- paste0("b", 1:8)
b <- c(rep(c("SUP_Parents", "SUP_Friends"), each = 2),
d "SUP_Parents", "SUP_Friends", "SE_Academic", "SE_Social")
<- paste0(b, "*", d)
e
<- list(SE_Academic = e[c(1, 3)],
reg SE_Social = e[c(2, 4)],
LS = e[c(5:8)])
<- list(SE_Academic = "SE_Social")
cov
<- list(b1b7 = "b1*b7",
ind b2b8 = "b2*b8",
totalind_eltern = "b1*b7 + b2*b8",
b3b7 = "b3*b7",
b4b8 = "b4*b8",
totalind_freunde = "b3*b7 + b4*b8",
total_eltern = "b1*b7 + b2*b8 + b5",
total_freunde = "b3*b7 + b4*b8 + b6")
<- write_lavaan(regression = reg, covariance = cov,
model indirect = ind, latent = lat)
cat(model)
## ##################################################
## # [---------------Latent variables---------------]
##
## SUP_Parents =~ sup_parents_p1 + sup_parents_p2 + sup_parents_p3
## SUP_Friends =~ sup_friends_p1 + sup_friends_p2 + sup_friends_p3
## SE_Academic =~ se_acad_p1 + se_acad_p2 + se_acad_p3
## SE_Social =~ se_social_p1 + se_social_p2 + se_social_p3
## LS =~ ls_p1 + ls_p2 + ls_p3
##
## ##################################################
## # [---------Regressions (Direct effects)---------]
##
## SE_Academic ~ b1*SUP_Parents + b3*SUP_Friends
## SE_Social ~ b2*SUP_Parents + b4*SUP_Friends
## LS ~ b5*SUP_Parents + b6*SUP_Friends + b7*SE_Academic + b8*SE_Social
##
## ##################################################
## # [------------------Covariances-----------------]
##
## SE_Academic ~~ SE_Social
##
## ##################################################
## # [--------Mediations (indirect effects)---------]
##
## b1b7 := b1*b7
## b2b8 := b2*b8
## totalind_eltern := b1*b7 + b2*b8
## b3b7 := b3*b7
## b4b8 := b4*b8
## totalind_freunde := b3*b7 + b4*b8
## total_eltern := b1*b7 + b2*b8 + b5
## total_freunde := b3*b7 + b4*b8 + b6