-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathIntro_to_lavaanPlot.Rmd
More file actions
179 lines (123 loc) · 7.99 KB
/
Copy pathIntro_to_lavaanPlot.Rmd
File metadata and controls
179 lines (123 loc) · 7.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
---
title: "Intro to lavaanPlot"
author: "Alex Lishinski"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Intro to lavaanPlot}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
## Introduction
The lavaan package is an excellent package for structural equation models, and the DiagrammeR package is an excellent package for producing nice looking graph diagrams. As of right now, the lavaan package has no built in plotting functions for models, and the available options from external packages don't look as nice and aren't as easy to use as DiagrammeR, in my opinion. Of course, you can use DiagrammeR to build path diagrams for your models, but it requires you to build the diagram specification manually. This package exists to streamline that process, allowing you to plot your lavaan models directly, without having to translate them into the DOT language specification that DiagrammeR uses.
## Package example
The package is very straightforward to use, simply call the `lavaanPlot` function with your lavaan model, adding whatever graph, node and edge attributes you want as a named list (graph attributes are specified as a standard default value that shows you what the other attribute lists should look like). For your reference, the available attributes can be found here:
https://rich-iannone.github.io/DiagrammeR/graphviz_and_mermaid.html#node-attributes
https://rich-iannone.github.io/DiagrammeR/graphviz_and_mermaid.html#edge-attributes
Here's a quick example using the `mtcars` data set.
First fit your lavaan model. The package supports plotting lavaan regression relationships and latent variable - indicator relationships.
```{r}
library(lavaan)
library(lavaanPlot)
model <- 'mpg ~ cyl + disp + hp
qsec ~ disp + hp + wt'
fit <- sem(model, data = mtcars)
summary(fit)
```
Then using that model fit object, simply call the `lavaanPlot` function, specifying your desired graph parameters.
```{r}
lavaanPlot(model = fit, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = FALSE)
```
## Plot customization options
You can also specify different variable labels using the a named list and the `labels` argument.
```{r}
labels <- list(mpg = "Miles Per Gallon", cyl = "Cylinders", disp = "Displacement", hp = "Horsepower", qsec = "Speed", wt = "Weight")
lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = FALSE)
```
An example showing latent variable relationships:
```{r}
HS.model <- ' visual =~ x1 + x2 + x3
textual =~ x4 + x5 + x6
speed =~ x7 + x8 + x9
'
fit <- cfa(HS.model, data=HolzingerSwineford1939)
lavaanPlot(model = fit, edge_options = list(color = "grey"))
```
You can label the plot edges with the coefficient values using `coefs = TRUE`.
```{r}
model <- 'mpg ~ cyl + disp + hp
qsec ~ disp + hp + wt'
fit <- sem(model, data = mtcars)
summary(fit)
lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE)
```
By default it will show all paths, but you can also specify whatever significance level you want using the `sig` argument to only show significant paths.
```{r}
# significant standardized paths only
lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, sig = .05)
```
You can also show standardized paths only with the `stand` argument.
```{r}
# All paths unstandardized
lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, stand = TRUE)
```
Same works for latent variable loadings
```{r}
HS.model <- ' visual =~ x1 + x2 + x3
textual =~ x4 + x5 + x6
speed =~ x7 + x8 + x9
'
fit <- cfa(HS.model, data=HolzingerSwineford1939)
labels = list(visual = "Visual Ability", textual = "Textual Ability", speed = "Speed Ability")
# Show coefs
lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE)
# Significant paths
lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, sig = .05)
# All paths standardized
lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, stand = TRUE)
```
You can also include double-sided edges to represent model covariances if you want:
```{r}
HS.model <- ' visual =~ x1 + x2 + x3
textual =~ x4 + x5 + x6
speed =~ x7 + x8 + x9
'
fit <- cfa(HS.model, data=HolzingerSwineford1939)
labels = list(visual = "Visual Ability", textual = "Textual Ability", speed = "Speed Ability")
# significant standardized paths only
lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE)
```
You can include significance stars as well using the `stars` option.
You can choose stars for regression paths, latent paths, or covariances. Specify which of the 3 you want ("regress", "latent", "covs").
```{r}
lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = "covs")
lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = "latent")
```
You can change the number of decimal places in the coefficient value labels as well with the `digits` option.
```{r}
lavaanPlot(model = fit, labels = labels, node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = TRUE, digits = 1)
```
## Graph Options
### Orientations with `rankdir`
You can also do additional options to modify the layout of your plots in certain ways.
The graph option `rankdir` allows you to change the overall orientation of the plot between TB (top-bottom; default), BT (bottom-top), RL (right-left) and LR (left-right):
```{r}
lavaanPlot(model = fit, labels = labels, graph_options = list(rankdir = "LR"), node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = TRUE, digits = 1)
```
```{r}
lavaanPlot(model = fit, labels = labels, graph_options = list(rankdir = "RL"), node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = TRUE, digits = 1)
```
```{r}
lavaanPlot(model = fit, labels = labels, graph_options = list(rankdir = "BT"), node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = TRUE, digits = 1)
```
### Layouts with `layout`
The graph option `layout` allows you to change the layout engine used to generate the plot between dot (the default), neato, circo, twopi, plus some others, see: https://graphviz.org/docs/layouts/. Your mileage may vary as to whether any of these work for a given graph.
```{r}
lavaanPlot(model = fit, labels = labels, graph_options = list(layout = "neato"), node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = TRUE, digits = 1)
```
```{r}
lavaanPlot(model = fit, labels = labels, graph_options = list(layout = "circo"), node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = TRUE, digits = 1)
```
```{r}
lavaanPlot(model = fit, labels = labels, graph_options = list(layout = "twopi"), node_options = list(shape = "box", fontname = "Helvetica"), edge_options = list(color = "grey"), coefs = TRUE, covs = TRUE, stars = TRUE, digits = 1)
```