Chapter 8 Latent Variable Models
# Parallel processing settings
plan(multisession(workers = parallel::detectCores(logical = FALSE)))
8.1 Data
<- read_rds("data/mtf.rds")
mtf <- read_rds("data/us.rds")
us <- read_rds("data/yrbs.rds") yrbs
8.2 Models
<- function(data, items, x, y, name, missing = "ml") {
fit # Center year
<- mutate(data, Year = Year - 2017)
data
# Contrast code sex
<- mutate(data, Sex = ifelse(Sex=="Male", -0.5, 0.5))
data
# Drop rows with missing predictor
<- drop_na(data, all_of(x))
data
# Drop rows where all outcome items are missing
<- drop_na(data, all_of(y))
data
# Mean-center predictors
<- data %>%
data mutate(
across(
all_of(x),
~as.numeric(scale(., center = TRUE, scale = FALSE))
)
)
# Ordered?
if (name=="YRBS") {
<- mutate(data, across(sad_lonely:suicide_3, ordered))
data = "listwise"
missing
}
# Create interaction terms because lavaan doesn't know how to
<- model.matrix(
newdata as.formula(str_glue("{y} ~ Sex * Year * {x}")),
data = data
-1] %>% # Take out the intercept column because it causes lavaan to break
)[,as.data.frame()
# Interaction term breaks lavaan so change to dot
names(newdata) <- str_replace_all(names(newdata), ":", ".")
# return(newdata)
<- cbind(data[,items], newdata)
newdata # Combine names of items to a string for lavaan model
<- paste0(items, collapse = " + ")
items_all
# Model strings
<- str_glue("{y} =~ {items_all}\n{y} ~ Sex + Year + Sex.Year")
sem0 <- str_glue("{y} =~ {items_all}\n{y} ~ Sex + Year + {x} + Sex.Year + Sex.{x} + Year.{x} + Sex.Year.{x}")
sem1
<- sem(sem0, data = newdata, missing = missing)
ml0 <- sem(sem1, data = newdata, missing = missing)
ml1
tibble(
data = name,
Technology = x,
Outcome = y,
ml0 = list(ml0),
ml1 = list(ml1)
)
}
%<-% fit(yrbs, c("sad_lonely", paste0("suicide_", 1:3)), "TV", "Suicide", "YRBS")
x1 %<-% fit(yrbs, c("sad_lonely", paste0("suicide_", 1:3)), "DV", "Suicide", "YRBS")
x2 %<-% fit(mtf, paste0("D_B_", 1:6), "TV", "Depression", "MTF")
x3 %<-% fit(mtf, paste0("D_B_", 1:6), "SM", "Depression", "MTF")
x4
<- c("sdqe", "sdqg", "sdql", "sdqr", "sdqv")
sdq_con <- c("sdqc", "sdqh", "sdqm", "sdqp", "sdqx")
sdq_emo
%<-% fit(us, sdq_con, "TV", "Conduct", "US")
x5 %<-% fit(us, sdq_con, "SM", "Conduct", "US")
x6 %<-% fit(us, sdq_emo, "TV", "Emotion", "US")
x7 %<-% fit(us, sdq_emo, "SM", "Emotion", "US")
x8
# Rename variables
<- bind_rows(x1,x2,x3,x4,x5,x6,x7,x8)
fits <- fits %>%
fits mutate(
Technology = ifelse(
%in% c("SM", "DV"),
Technology "Social media / device",
"Television"
)%>%
) arrange(Outcome, Technology)
8.3 Results
<- fits %>%
coefs mutate(p = map(ml1, ~tidy(., conf.int = TRUE))) %>%
unnest(p) %>%
filter(op == "~") %>%
separate(term, c("lhs", "rhs"), sep = " ~ ") %>%
mutate(N = map_dbl(ml1, nobs)) %>%
mutate(N = scales::comma(N, accuracy = 1))
%>%
coefs mutate(Parameter = str_replace(rhs, "SM|DV|TV", "Technology")) %>%
mutate(Parameter = str_replace_all(Parameter, "\\.", ":")) %>%
mutate(Parameter = fct_inorder(Parameter)) %>%
mutate(Outcome = fct_rev(Outcome)) %>%
ggplot(aes(estimate, Outcome, shape = Technology, fill = p.value < 0.05)) +
scale_shape_manual(values = c(21, 22)) +
scale_fill_manual(values = c("white", "black"), guide = FALSE) +
scale_x_continuous(
"Parameter estimate",
breaks = scales::pretty_breaks(),
expand = expansion(.25)
+
) geom_vline(xintercept = 0, lty = 2, size = .25) +
geom_linerangeh(
aes(xmin = conf.low, xmax = conf.high), size = .25,
position = position_dodge2v(.4), show.legend = FALSE
+
) geom_point(
size = 2, position = position_dodge2v(.4),
+
) # geom_text(
# aes(label = N), size = 2, vjust = 2,
# position = position_dodge2v(.4)
# ) +
facet_wrap("Parameter", scales = "free_x", nrow = 2) +
theme(
legend.position = c(.875, .25),
axis.title.y = element_blank(),
panel.spacing.x = unit(12, "pt")
)
# Numbers
%>%
coefs mutate(coef = str_glue("{lhs} {op} {rhs}")) %>%
select(data:Outcome, coef, estimate:conf.high)
%>%
coefs distinct(data, Technology, Outcome, N)
Just time
%>%
fits mutate(p = map(ml0, ~tidy(., conf.int = TRUE))) %>%
unnest(p) %>%
filter(op == "~") %>%
separate(term, c("lhs", "rhs"), sep = " ~ ") %>%
# mutate(
# Parameter = factor(rhs, levels = c("Year", "Technology", "Year x Technology"))
# ) %>%
mutate(Outcome = fct_rev(Outcome)) %>%
ggplot(aes(estimate, Outcome, shape = Technology, fill = p.value < 0.05)) +
scale_shape_manual(values = c(21, 22)) +
scale_fill_manual(values = c("white", "black"), guide = FALSE) +
scale_x_continuous(
"Parameter estimate",
breaks = scales::pretty_breaks(),
expand = expansion(.25)
+
) geom_vline(xintercept = 0, lty = 2, size = .25) +
geom_linerangeh(
aes(xmin = conf.low, xmax = conf.high), size = .25,
position = position_dodge2v(.4), show.legend = FALSE
+
) geom_point(
size = 2, position = position_dodge2v(.4),
+
) facet_wrap("rhs", scales = "free_x", nrow = 1) +
theme(
legend.position = "bottom",
axis.title.y = element_blank(),
panel.spacing.x = unit(12, "pt")
)
options(width = 120)
library(sessioninfo)
session_info()
## ─ Session info ───────────────────────────────────────────────────────────────────────────────────────────────────────
## setting value
## version R version 4.0.3 (2020-10-10)
## os macOS Big Sur 10.16
## system x86_64, darwin17.0
## ui X11
## language (EN)
## collate en_GB.UTF-8
## ctype en_GB.UTF-8
## tz Europe/London
## date 2021-03-01
##
## ─ Packages ───────────────────────────────────────────────────────────────────────────────────────────────────────────
## package * version date lib source
## assertthat 0.2.1 2019-03-21 [1] CRAN (R 4.0.0)
## backports 1.2.1 2020-12-09 [1] CRAN (R 4.0.2)
## bookdown 0.21.6 2021-03-01 [1] Github (rstudio/bookdown@ca0145f)
## broom * 0.7.5.9000 2021-03-01 [1] Github (tidymodels/broom@0b3528b)
## bslib 0.2.4 2021-01-25 [1] CRAN (R 4.0.3)
## cellranger 1.1.0 2016-07-27 [1] CRAN (R 4.0.0)
## cli 2.3.1 2021-02-23 [1] CRAN (R 4.0.3)
## codetools 0.2-18 2020-11-04 [1] CRAN (R 4.0.2)
## colorspace 2.0-0 2020-11-11 [1] CRAN (R 4.0.2)
## crayon 1.4.1 2021-02-08 [1] CRAN (R 4.0.3)
## DBI 1.1.1 2021-01-15 [1] CRAN (R 4.0.2)
## dbplyr 2.1.0 2021-02-03 [1] CRAN (R 4.0.2)
## digest 0.6.27 2020-10-24 [1] CRAN (R 4.0.2)
## dplyr * 1.0.4 2021-02-02 [1] CRAN (R 4.0.2)
## ellipsis 0.3.1 2020-05-15 [1] CRAN (R 4.0.0)
## evaluate 0.14 2019-05-28 [1] CRAN (R 4.0.0)
## fansi 0.4.2 2021-01-15 [1] CRAN (R 4.0.2)
## farver 2.0.3 2020-01-16 [1] CRAN (R 4.0.0)
## forcats * 0.5.1 2021-01-27 [1] CRAN (R 4.0.2)
## fs 1.5.0 2020-07-31 [1] CRAN (R 4.0.2)
## future * 1.21.0 2020-12-10 [1] CRAN (R 4.0.2)
## generics 0.1.0 2020-10-31 [1] CRAN (R 4.0.2)
## ggplot2 * 3.3.3 2020-12-30 [1] CRAN (R 4.0.2)
## ggstance * 0.3.5 2020-12-17 [1] CRAN (R 4.0.2)
## globals 0.14.0 2020-11-22 [1] CRAN (R 4.0.2)
## glue 1.4.2 2020-08-27 [1] CRAN (R 4.0.2)
## gtable 0.3.0 2019-03-25 [1] CRAN (R 4.0.0)
## haven 2.3.1 2020-06-01 [1] CRAN (R 4.0.0)
## highr 0.8 2019-03-20 [1] CRAN (R 4.0.0)
## hms 1.0.0 2021-01-13 [1] CRAN (R 4.0.2)
## htmltools 0.5.1.1 2021-01-22 [1] CRAN (R 4.0.2)
## httr 1.4.2 2020-07-20 [1] CRAN (R 4.0.2)
## jquerylib 0.1.3 2020-12-17 [1] CRAN (R 4.0.2)
## jsonlite 1.7.2 2020-12-09 [1] CRAN (R 4.0.2)
## knitr * 1.31 2021-01-27 [1] CRAN (R 4.0.2)
## lavaan * 0.6-7 2020-07-31 [1] CRAN (R 4.0.2)
## lifecycle 1.0.0 2021-02-15 [1] CRAN (R 4.0.2)
## listenv 0.8.0 2019-12-05 [1] CRAN (R 4.0.0)
## lubridate 1.7.9.2 2020-11-13 [1] CRAN (R 4.0.2)
## magrittr 2.0.1 2020-11-17 [1] CRAN (R 4.0.2)
## mnormt 2.0.2 2020-09-01 [1] CRAN (R 4.0.2)
## modelr 0.1.8 2020-05-19 [1] CRAN (R 4.0.0)
## munsell 0.5.0 2018-06-12 [1] CRAN (R 4.0.0)
## pacman 0.5.1 2019-03-11 [1] CRAN (R 4.0.0)
## parallelly 1.23.0 2021-01-04 [1] CRAN (R 4.0.2)
## pbivnorm 0.6.0 2015-01-23 [1] CRAN (R 4.0.0)
## pillar 1.5.0 2021-02-22 [1] CRAN (R 4.0.3)
## pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.0.0)
## purrr * 0.3.4 2020-04-17 [1] CRAN (R 4.0.0)
## R6 2.5.0 2020-10-28 [1] CRAN (R 4.0.2)
## Rcpp 1.0.6 2021-01-15 [1] CRAN (R 4.0.2)
## readr * 1.4.0 2020-10-05 [1] CRAN (R 4.0.2)
## readxl 1.3.1 2019-03-13 [1] CRAN (R 4.0.0)
## reprex 1.0.0 2021-01-27 [1] CRAN (R 4.0.2)
## rlang 0.4.10 2020-12-30 [1] CRAN (R 4.0.2)
## rmarkdown 2.7.2 2021-03-01 [1] Github (rstudio/rmarkdown@9bfaf4a)
## rstudioapi 0.13 2020-11-12 [1] CRAN (R 4.0.2)
## rvest 0.3.6 2020-07-25 [1] CRAN (R 4.0.2)
## sass 0.3.1 2021-01-24 [1] CRAN (R 4.0.2)
## scales 1.1.1 2020-05-11 [1] CRAN (R 4.0.0)
## sessioninfo * 1.1.1 2018-11-05 [1] CRAN (R 4.0.0)
## stringi 1.5.3 2020-09-09 [1] CRAN (R 4.0.2)
## stringr * 1.4.0 2019-02-10 [1] CRAN (R 4.0.0)
## tibble * 3.1.0 2021-02-25 [1] CRAN (R 4.0.2)
## tidyr * 1.1.2 2020-08-27 [1] CRAN (R 4.0.2)
## tidyselect 1.1.0 2020-05-11 [1] CRAN (R 4.0.0)
## tidyverse * 1.3.0 2019-11-21 [1] CRAN (R 4.0.0)
## tmvnsim 1.0-2 2016-12-15 [1] CRAN (R 4.0.0)
## utf8 1.1.4 2018-05-24 [1] CRAN (R 4.0.0)
## vctrs 0.3.6 2020-12-17 [1] CRAN (R 4.0.2)
## withr 2.4.1 2021-01-26 [1] CRAN (R 4.0.2)
## xfun 0.21 2021-02-10 [1] CRAN (R 4.0.2)
## xml2 1.3.2 2020-04-23 [1] CRAN (R 4.0.0)
## yaml 2.2.1 2020-02-01 [1] CRAN (R 4.0.0)
##
## [1] /Library/Frameworks/R.framework/Versions/4.0/Resources/library