Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research...
Transcript of Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research...
![Page 1: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/1.jpg)
Structural Equation Modelingwith lavaan
Terrence D. Jorgensen & Leslie Shaw
Saturday Seminar SeriesQuantitative Training Program
Center for Research Methods and Data Analysis
![Page 2: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/2.jpg)
Acknowledgements
• Paul Johnson for getting us started with lavaan before it was on anyone else’s radar
• Yves Rossell for creating such easy to use, comprehensive, free software in his free time
PLEASE CITE IT IF YOU USE ITRosseel, Y. (2012). lavaan: An R package for
structural equation modeling. Journal of Statistical Software, 48, 1–36.
2
![Page 3: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/3.jpg)
In this workshop, you will see
• An introduction to lavaan• How to import raw and summary data• lavaan syntax, commands, and options• How to request a variety of specific results• See examples in the form of exercises• Learn about some additional features
3
![Page 4: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/4.jpg)
What is lavaan?• Created by Yves Rossell to offer an
affordable, open-source alternative to Mplus• Free!
– as in free speech AND free beer• Open-source:
– no estimation method is secret– open to peer-review, like science
• Intuitive syntax, similar to Mplus
4
![Page 5: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/5.jpg)
What is lavaan?• Part of R
– Unlike Mplus and LISREL, you can do data management and other analyses easily in the same place you run your model
• Interactive– Unlike Mplus and LISREL, you don’t need to run
an analysis again if you want additional output– All output is created and stored in an object, from
which you can easily extract anything you want
5
![Page 6: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/6.jpg)
Help with lavaan• Examples are provided on his web site:
http://lavaan.ugent.be/• Also in his paper on lavaan
http://www.jstatsoft.org/v48/i02• Find help files in R by typing on the
command line:> help(package = lavaan)
• KUant Guide # 21http://crmda.ku.edu/main/KUant_Guides
6
![Page 7: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/7.jpg)
Importing Data Files• Can import *.dat, *.txt, *.csv into R• With the “foreign” package, can import files
from SPSS, SAS, Stata…install.packages("foreign")library(foreign)help(package = foreign)
• Can use – Raw data – Sufficient statistics (correlation/covariance matrix,
means, standard deviations)
7
![Page 8: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/8.jpg)
Data Files• R uses “NA” as the missing value code
– Unlike Mplus, which requires a numerical code (e.g., −999), which increases chance of human error (e.g., −99 or −9999)
• Variable names can be anything starting with a letter– Unlike Mplus, no limit of 8 characters– Unlike Mplus, you can import data with variable
names already in the file
8
![Page 9: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/9.jpg)
Descriptive Statistics
9
• We won’t provide an intro to R, but KUant Guide #20 is available
• Open the Syntax Guide we provided: “exampleCode.R”
• Read in data from example *.dat files
![Page 10: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/10.jpg)
Syntax Operatorslavaan operator
• =~ “defined by”
• ~~ “is correlated with”
• ~ “is regressed on”
• var ~ 1 (latent mean / intercept)
• value*var (fix a value)
• start(value)* (starting value)
• c(“label”)*var (label a variable)
Mplus keyword
• BY
• WITH
• ON
• [var]
• var@value
• var*value
• var (label)
10
![Page 11: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/11.jpg)
Main Commands• lavaan(model, data) Run any type
• cfa(model, data) Run a CFA
• sem(model, data) Run an SEM
• growth(model, data) Run a growth curve
11
![Page 12: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/12.jpg)
Other Arguments for Commands
fit1 <- sem(mod1, data=myData, EXTRAS)
You can specify other options for EXTRAS– Choose a robust estimatorestimator = "ML" or "MLM", "MLR"
– FIML estimation for missing datamissing = "fiml" or "ml", "direct"
– Bootstrap for robust SEsbootstrap = 500 or 1000, 2000
12
![Page 13: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/13.jpg)
Other Arguments for Commands
– Use sufficient statistics instead of raw datasample.cov = myCovsample.mean = myMeanssample.nobs = mySampleSize
– Automatically choose identification methodauto.fix.first = TRUE (default)std.lv = TRUE
– Effects-coding method possible, but not automatic
13
![Page 14: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/14.jpg)
Other Arguments for Commands– Specify variables as ordinal for proper estimationordered = c("Var1", "Var2")
– Specify grouping variable for multiple-group modelsgroup = "myGroupingVariable"
– Automatically constrain estimates across groupsgroup.equal = "loadings"group.equal = c("loadings",
"intercepts")group.equal = c("loadings",
"regressions")
14
![Page 15: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/15.jpg)
Step 1: Model Syntaxmod1 <- "
## factor loadingsAgency =~ Agency1 + Agency2 + Agency3Intrin =~ Intrin1 + Intrin2 + Intrin3Extrin =~ Extrin1 + Extrin2 + Extrin3Positive =~ PosAFF1 + PosAFF2 + PosAFF3
## correlated residual variancesIntrin3 ~~ Extrin3
## latent regression pathsPositive ~ Agency + Intrin + Extrin
"
• Save model as a string of text called mod1
15
![Page 16: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/16.jpg)
Step 2: Fit the Model
Fit the model to the data
fit1 <- sem(mod1, data = myData)
(specify extra arguments as necessary)
All model results are saved in the object “fit1”
16
![Page 17: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/17.jpg)
Step 3: Request Model OutputThere are several ways to extract results. • Basic summarysummary(fit1)
• Get fit stats and modification indicessummary(fit1, fit.measures = TRUE,
modindices = TRUE)
• Get standardized solution & R2
summary(fit1, standardized = TRUE, r.squared = TRUE)
17
![Page 18: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/18.jpg)
Step 3: Request Model OutputUse parameterEstimates() function• parameterEstimates(fit1)
Use the inspect() function• inspect(fit1, "coef")
• inspect(fit1, "std")
• inspect(fit1, "se")
• inspect(fit1, "fit")
• inspect(fit1, "modindices")
• inspect(fit1, "rsquare")
18
![Page 19: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/19.jpg)
Model ComparisonsUse group.equal argument to test measurement invariance• group.equal=c("loadings","intercepts")
Use R’s anova() function to compare these and other nested models using Δχ2 test• anova(fit1, fit2)
19
![Page 20: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/20.jpg)
Exercise #1
Let’s start simple.
Create syntax for a multiple regression• DV = y• IVs = x1 and x2
• Use “ex1” example data
20
![Page 21: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/21.jpg)
Regression Syntax
21
mod1 <- 'y ~ x1 + x2'
fit1 <- sem(mod1, data = ex1, meanstructure = TRUE)
summary(fit1, rsquare = TRUE)
## compare to regression as a linear model m1 <- lm(y ~ x1 + x2, data = ex1)summary(m1)
![Page 22: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/22.jpg)
Regression Output
22
Compare intercept, slopes, residual variance of outcome, and R2
![Page 23: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/23.jpg)
Exercise #2
23
a1
a2
b1
b2
Write model syntax for this Path Analysis.Fit the model to the “ex2” example data.* We can also test mediation in lavaan!
![Page 24: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/24.jpg)
Path Analysis Syntax
24
mod2 <- ' ## regressionsy1 ~ a1*x1 + x2 + x3y2 ~ a2*x1 + x2 + x3y3 ~ b1*y1 + b2*y2 + x2
## define mediation parameters (indirect effects)ind1 := a1 * b1ind2 := a2 * b2totalind := ind1 + ind2
## correlated residual variancesy1 ~~ y2 '
fit2 <- sem(mod2, data = ex2, meanstructure = TRUE, se = "boot", bootstrap = 500)
summary(fit2, fit.measures=TRUE, standardized=TRUE)
![Page 25: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/25.jpg)
Path Analysis Output
25
![Page 26: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/26.jpg)
Exercise #3
26
Positive Negative
11 21 31 42 52 62
21
11 22 33 44 55 66
Great UnhappyDownSadHappyCheerful
1* 1*
NOTE: “ex3” data uses sufficient statistics as input
![Page 27: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/27.jpg)
CFA Syntax
27
mod3 <- ' ## factor loadingsPositive =~ great + cheerful + happyNegative =~ sad + down + unhappy '
fit3 <- cfa(mod3, sample.cov = mycov, sample.mean = mymeans, sample.nobs = nObs, std.lv = TRUE, meanstructure = TRUE)
summary(fit3, standardized = TRUE, fit.measures = TRUE)
![Page 28: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/28.jpg)
CFA Output
28
![Page 29: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/29.jpg)
Exercise #4
29
• Fit another 2-factor CFA, this time both are Positive Affect, measured on 2 occasions
• Add correlated residuals among variables measured repeatedly
• Use labels to constrain loadings across time (longitudinal invariance)
• Free factor variance at 2nd occasion
![Page 30: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/30.jpg)
Exercise #4
30
Positive1
Positive2
11 21 31 * 11 * 21 * 31
21
11 22 33 44 55 66
Great1
Happy2
Cheerful2
Great2
Happy1
Cheerful1
1* 22
41
52
63
![Page 31: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/31.jpg)
Longitudinal CFA Syntax
31
mod4 <- ' ## factor loadingsPos1 =~ L1*great1 + L2*cheerful1 + L3*happy1Pos2 =~ L1*great2 + L2*cheerful2 + L3*happy2
## free factor variance at second timePos2 ~~ NA*Pos2
## correlated residual variancesgreat1 ~~ great2cheerful1 ~~ cheerful2happy1 ~~ happy2 '
fit4 <- cfa(mod4, data = ex4, std.lv = TRUE)
summary(fit4, standardized=TRUE, fit.measures=TRUE)
![Page 32: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/32.jpg)
Longitudinal CFA Output
32
![Page 33: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/33.jpg)
Exercise #5
33
Agency(1)
Intrinsic(2)
Extrinsic(3)
PositiveAffect (4)
41
42
43
21
32
31
1*
1*
1*1*
NOTE: Each latent variable has 3 indicators, see “ex5” data.
This example has missing data!
![Page 34: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/34.jpg)
SEM Syntax (1)
34
mod5 <- ' ## factor loadingsAgency =~ c(L1, L1)*Agency1 + Agency2 + Agency3Intrinsic =~ Intrin1 + Intrin2 + Intrin3Extrinsic =~ Extrin1 + Extrin2 + Extrin3Positive =~ PosAFF1 + PosAFF2 + PosAFF3
## latent regression pathsPositive ~ Agency + Intrinsic + Extrinsic '
fit5 <- sem(mod5, data = ex5, std.lv = TRUE, group = "Sex", missing = "fiml", meanstructure = TRUE)
summary(fit5, standardized=TRUE, fit.measures=TRUE)
![Page 35: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/35.jpg)
SEM Syntax (2)
35
## weak invariancefit5 <- sem(mod5, data = ex5, std.lv = TRUE,
meanstructure = TRUE, group = "Sex", group.equal = "loadings", missing = "fiml")
summary(fit5, standardized=TRUE, fit.measures=TRUE)
## constrain regressions to equality, toofit5 <- sem(mod5, data = ex5, std.lv = TRUE,
missing = "fiml", meanstructure = TRUE, group = "Sex", group.equal = c("loadings", "regressions"))
summary(fit5, standardized = TRUE, fit.measures = TRUE)
![Page 36: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/36.jpg)
SEM Output
36
![Page 37: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/37.jpg)
Exercise #6
37
NOTE: Fix each loading.Constrain residuals to equality.
0*
3*
Neg1 Neg2 Neg3 Neg4
Intercept Slope
1* 1* 1*1*
2*1*
11 22
21
11 11 11 11
![Page 38: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/38.jpg)
Growth Curve Syntax
38
mod6 <- ' ## initial status and shape of changeintercept =~ 1*NegT1 + 1*NegT2 + 1*NegT3 + 1*NegT4slope =~ 0*NegT1 + 1*NegT2 + 2*NegT3 + 3*NegT4
## constraint residual variance to equality over timeNegT1 ~~ th1*NegT1NegT2 ~~ th1*NegT2NegT3 ~~ th1*NegT3NegT4 ~~ th1*NegT4 '
fit6 <- growth(mod6, data = ex6)
summary(fit6, standardized=TRUE, fit.measures=TRUE)
![Page 39: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/39.jpg)
Growth Curve Output
39
![Page 40: Structural Equation Modeling with lavaan · Quantitative Training Program Center for Research Methods and Data Analysis. Acknowledgements • Paul Johnson for getting us started with](https://reader036.fdocuments.us/reader036/viewer/2022062402/5fc3271847344976c12da558/html5/thumbnails/40.jpg)
Troubleshooting• Check if model is identified and specified
correctly
• Draw a diagram of your model with commands for each parameter
• Check data file is reading in correctly– Eyeball your data file for funny patterns– Check your missing codes – Warning Messages
40