Load packages and data.
#packages
library(pacman)
p_load(kirkegaard, readr, dplyr, haven, lavaan, igraph, ggraph)
options(digits = 2, scipen = 5)
#data
d = haven::read_spss("data/VES.sav")
#rename variables to more sensible names
d %<>% rename(
#Wide Range Achievement Test (WRAT)
WRAT = WR01008,
#California Verbal Learning Test (CVLT)
CVLT = CV01144,
#Wisconsin Card Sort Test (WCST)
WCST = WCS25,
#Wechsler Adult Intelligence Scale-Revised (WAIS-R) subtests
WAIS_BD = WA01012B,
WAIS_GI = WA01011B,
#Rey±Osterrieth Complex Figure Drawing
copy_direct = RE01011, #direct
copy_immediate = RE01012, #immediate recall
copy_delayed = RE01013, #delayed recall
#Paced Auditory Serial Addition Test (PASAT)
PASAT = SPASAT,
#Grooved Pegboard Test (GPT)
GPT_left = LEFTREV,
GPT_right = RIGHTREV,
#Word List Generation Test (WLGT), verbal fluency
WLGT = FAS,
#education
Education = EDUC
) %>% mutate(
#average of the memorized copy tests
copy_combined = (standardize(copy_immediate) + standardize(copy_delayed))/2
)
Ad hoc functions.
#function to regress out early g from a variable
regressor = function(x) {
#make model
model_ = x + " ~ g_early"
#fit
lm(model_, data = d, na.action = na.exclude) %>%
#resids
resid
}
Extract g at different times.
#g tests
g_tests_early = c("VESS", "VE", "AR", "ARSS", "PA", "GIT", "AFQT")
g_tests_later = c("WAIS_BD", "WAIS_GI", "WRAT", "PASAT", "WLGT", "copy_combined", "CVLT", "WCST", "GPT_left", "GPT_right")
g_tests = c(g_tests_early, g_tests_later)
#test correlations
wtd.cors(d[g_tests])
## VESS VE AR ARSS PA GIT AFQT WAIS_BD WAIS_GI WRAT
## VESS 1.00 0.82 0.66 0.69 0.48 0.62 0.68 0.45 0.72 0.77
## VE 0.82 1.00 0.70 0.64 0.52 0.66 0.72 0.44 0.73 0.75
## AR 0.66 0.70 1.00 0.79 0.58 0.59 0.74 0.50 0.64 0.59
## ARSS 0.69 0.64 0.79 1.00 0.54 0.55 0.69 0.53 0.62 0.58
## PA 0.48 0.52 0.58 0.54 1.00 0.47 0.73 0.63 0.48 0.41
## GIT 0.62 0.66 0.59 0.55 0.47 1.00 0.65 0.42 0.58 0.52
## AFQT 0.68 0.72 0.74 0.69 0.73 0.65 1.00 0.62 0.63 0.58
## WAIS_BD 0.45 0.44 0.50 0.53 0.63 0.42 0.62 1.00 0.45 0.38
## WAIS_GI 0.72 0.73 0.64 0.62 0.48 0.58 0.63 0.45 1.00 0.65
## WRAT 0.77 0.75 0.59 0.58 0.41 0.52 0.58 0.38 0.65 1.00
## PASAT 0.44 0.41 0.52 0.56 0.37 0.37 0.43 0.39 0.37 0.42
## WLGT 0.46 0.44 0.37 0.37 0.29 0.31 0.36 0.28 0.41 0.50
## copy_combined 0.32 0.31 0.34 0.39 0.46 0.32 0.46 0.50 0.35 0.28
## CVLT 0.33 0.32 0.33 0.36 0.26 0.25 0.31 0.27 0.33 0.31
## WCST 0.36 0.33 0.36 0.40 0.33 0.28 0.37 0.36 0.33 0.29
## GPT_left 0.23 0.21 0.21 0.24 0.26 0.19 0.27 0.31 0.19 0.20
## GPT_right 0.22 0.20 0.20 0.24 0.26 0.17 0.25 0.30 0.17 0.20
## PASAT WLGT copy_combined CVLT WCST GPT_left GPT_right
## VESS 0.44 0.46 0.32 0.33 0.36 0.23 0.22
## VE 0.41 0.44 0.31 0.32 0.33 0.21 0.20
## AR 0.52 0.37 0.34 0.33 0.36 0.21 0.20
## ARSS 0.56 0.37 0.39 0.36 0.40 0.24 0.24
## PA 0.37 0.29 0.46 0.26 0.33 0.26 0.26
## GIT 0.37 0.31 0.32 0.25 0.28 0.19 0.17
## AFQT 0.43 0.36 0.46 0.31 0.37 0.27 0.25
## WAIS_BD 0.39 0.28 0.50 0.27 0.36 0.31 0.30
## WAIS_GI 0.37 0.41 0.35 0.33 0.33 0.19 0.17
## WRAT 0.42 0.50 0.28 0.31 0.29 0.20 0.20
## PASAT 1.00 0.36 0.29 0.29 0.28 0.22 0.23
## WLGT 0.36 1.00 0.22 0.28 0.21 0.16 0.17
## copy_combined 0.29 0.22 1.00 0.33 0.27 0.23 0.20
## CVLT 0.29 0.28 0.33 1.00 0.19 0.11 0.12
## WCST 0.28 0.21 0.27 0.19 1.00 0.20 0.19
## GPT_left 0.22 0.16 0.23 0.11 0.20 1.00 0.63
## GPT_right 0.23 0.17 0.20 0.12 0.19 0.63 1.00
#extract g - all data
fa_g = fa(d[g_tests])
d$g = fa_g$scores %>% as.vector
#method variance
#only run manually because this is slow!
if (F) {
fa_method_variance = silence(fa_all_methods(d[g_tests]))
fa_method_variance$scores %>% wtd.cors %>% MAT_half %>% averages()
}
#g - early life
fa_g_early = fa(d[g_tests_early])
d$g_early = fa_g_early$scores %>% as.vector
#g - later life
fa_g_later = fa(d[g_tests_later])
d$g_later = fa_g_later$scores %>% as.vector
#g - gain
d$g_gain = d$g_later - d$g_early
#cors
wtd.cors(d[c("Education", "g", "g_early", "g_later", "g_gain")]) %>% round(2)
## Education g g_early g_later g_gain
## Education 1.00 0.57 0.55 0.54 -0.06
## g 0.57 1.00 0.99 0.92 -0.22
## g_early 0.55 0.99 1.00 0.85 -0.36
## g_later 0.54 0.92 0.85 1.00 0.18
## g_gain -0.06 -0.22 -0.36 0.18 1.00
#plots
GG_denhist(d, "g_early", vline = NULL)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning: Removed 106 rows containing non-finite values (stat_bin).
## Warning: Removed 106 rows containing non-finite values (stat_density).
silence(ggsave("figures/g_early_dist.png"))
GG_denhist(d, "g_later", vline = NULL)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning: Removed 36 rows containing non-finite values (stat_bin).
## Warning: Removed 36 rows containing non-finite values (stat_density).
silence(ggsave("figures/g_later_dist.png"))
GG_denhist(d, "g_gain", vline = NULL)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning: Removed 141 rows containing non-finite values (stat_bin).
## Warning: Removed 141 rows containing non-finite values (stat_density).
silence(ggsave("figures/g_gain_dist.png"))
GG_scatter(d, "Education", "g_gain", case_names = F, text_pos = "tl")
silence(ggsave("figures/education_g_gains.png"))
simple_path_model = "
g_later ~ g_early + Education
Education ~ g_early
"
simple_path = sem(simple_path_model, data = d, std.ov = T)
parameterestimates(simple_path)
## lhs op rhs est se z pvalue ci.lower ci.upper
## 1 g_later ~ g_early 0.79 0.009 85 0 0.773 0.81
## 2 g_later ~ Education 0.11 0.009 12 0 0.093 0.13
## 3 Education ~ g_early 0.55 0.013 43 0 0.524 0.57
## 4 g_later ~~ g_later 0.26 0.006 46 0 0.253 0.28
## 5 Education ~~ Education 0.70 0.015 46 0 0.670 0.73
## 6 g_early ~~ g_early 1.00 0.000 NA NA 1.000 1.00
Are gains g-loaded?
#Add regressed versions of later life tests
for (test_ in g_tests_later) {
#regress and save
d[[test_ + "_adj"]] = regressor(test_)
}
#Jensen's method - Education x g for all data
fa_Jensens_method(fa = fa_g, criterion = "Education", df = d)
## Using Pearson correlations for the criterion-indicators relationships.
#Education IQ gains on g?
edu_g_gains = wtd.cors(d[c("Education", g_tests_later + "_adj")])
fa_Jensens_method(fa = fa_g_later, criterion = edu_g_gains[-1, 1], df = d)
#Model of g Before we can use SEM to determine whether IQ gains are plausibly on g or not, we need to figure out how to model the data well.
model_basic = "
g_early =~ VESS + VE + AR + ARSS + PA + GIT + AFQT
g_later =~ WAIS_BD + WAIS_GI + WRAT + PASAT + WLGT + copy_direct + copy_delayed + copy_immediate + CVLT + WCST + GPT_left + GPT_right
#correlated errors
GPT_left ~~ GPT_right
VESS ~~ VE
PA ~~ AFQT
AR ~~ ARSS
copy_delayed ~~ copy_immediate
copy_delayed ~~ copy_direct
copy_immediate ~~ copy_direct
"
model_basic2 = "
g_later =~ WAIS_BD + WAIS_GI + WRAT + PASAT + WLGT + copy_direct + copy_delayed + copy_immediate + CVLT + WCST + GPT_left + GPT_right
#correlated errors
GPT_left ~~ GPT_right
copy_delayed ~~ copy_immediate
copy_delayed ~~ copy_direct
copy_immediate ~~ copy_direct
"
model_g = model_basic + "
#g stability
g_later ~ g_early"
model_g2 = model_basic2 + "
#g stability
g_later ~ g_early"
#basic with two g's
sem_basic = sem(model_g, data = d, std.ov = T, orthogonal = T)
fit_measures = c("cfi", "gfi", "tli", "rmsea", "srmr", "AIC")
sem_basic %>% fitmeasures(fit.measures = fit_measures)
## cfi gfi tli rmsea srmr aic
## 0.908 0.867 0.891 0.089 0.060 183970.813
sem_basic %>% resid
## $type
## [1] "raw"
##
## $cov
## VESS VE AR ARSS PA GIT AFQT WAIS_B
## VESS 0.000
## VE 0.000 0.000
## AR -0.039 -0.002 0.000
## ARSS 0.005 -0.046 0.000 0.000
## PA -0.069 -0.041 0.047 0.024 0.000
## GIT 0.003 0.039 0.000 -0.030 -0.002 0.000
## AFQT -0.039 -0.001 0.056 0.021 0.000 0.039 0.000
## WAIS_BD -0.067 -0.087 0.005 0.042 0.240 -0.020 0.113 0.000
## WAIS_GI 0.048 0.050 -0.007 -0.010 -0.029 0.013 -0.035 -0.040
## WRAT 0.114 0.087 -0.038 -0.031 -0.085 -0.035 -0.067 -0.100
## PASAT -0.024 -0.060 0.075 0.124 0.014 -0.027 -0.026 0.044
## WLGT 0.032 0.007 -0.045 -0.041 -0.040 -0.058 -0.064 -0.036
## copy_direct -0.022 -0.057 0.000 0.053 0.120 -0.034 0.032 0.136
## copy_delayed -0.070 -0.084 -0.030 0.020 0.162 -0.014 0.069 0.208
## copy_immediate -0.068 -0.082 -0.032 0.022 0.165 -0.011 0.070 0.205
## CVLT -0.015 -0.035 -0.004 0.027 -0.005 -0.047 -0.026 0.014
## WCST -0.009 -0.044 0.007 0.048 0.051 -0.028 0.004 0.080
## GPT_left -0.023 -0.044 -0.026 0.004 0.073 -0.019 0.025 0.121
## GPT_right -0.018 -0.041 -0.032 0.015 0.077 -0.028 0.017 0.123
## WAIS_G WRAT PASAT WLGT cpy_dr cpy_dl cpy_mm CVLT
## VESS
## VE
## AR
## ARSS
## PA
## GIT
## AFQT
## WAIS_BD
## WAIS_GI 0.000
## WRAT 0.031 0.000
## PASAT -0.079 -0.017 0.000
## WLGT 0.006 0.103 0.070 0.000
## copy_direct -0.047 -0.055 0.019 -0.030 0.000
## copy_delayed -0.020 -0.086 0.027 -0.016 0.000 0.000
## copy_immediate -0.021 -0.088 0.029 -0.019 0.000 0.000 0.000
## CVLT 0.001 -0.007 0.061 0.063 0.036 0.142 0.131 0.000
## WCST -0.021 -0.052 0.039 -0.020 0.106 0.065 0.065 0.012
## GPT_left -0.049 -0.028 0.055 0.006 0.100 0.090 0.092 -0.013
## GPT_right -0.053 -0.030 0.070 0.021 0.106 0.070 0.065 -0.003
## WCST GPT_lf GPT_rg
## VESS
## VE
## AR
## ARSS
## PA
## GIT
## AFQT
## WAIS_BD
## WAIS_GI
## WRAT
## PASAT
## WLGT
## copy_direct
## copy_delayed
## copy_immediate
## CVLT
## WCST 0.000
## GPT_left 0.063 0.000
## GPT_right 0.061 0.000 0.000
##
## $mean
## VESS VE AR ARSS PA
## 0 0 0 0 0
## GIT AFQT WAIS_BD WAIS_GI WRAT
## 0 0 0 0 0
## PASAT WLGT copy_direct copy_delayed copy_immediate
## 0 0 0 0 0
## CVLT WCST GPT_left GPT_right
## 0 0 0 0
#with with only 1 g
sem_basic2 = sem(model_g2, data = d, std.ov = T, orthogonal = T)
fit_measures = c("cfi", "gfi", "tli", "rmsea", "srmr", "AIC")
sem_basic2 %>% fitmeasures(fit.measures = fit_measures)
## cfi gfi tli rmsea srmr aic
## 0.937 0.958 0.920 0.081 0.060 133362.613
sem_basic2 %>% resid
## $type
## [1] "raw"
##
## $cov
## WAIS_B WAIS_G WRAT PASAT WLGT cpy_dr cpy_dl cpy_mm
## WAIS_BD 0.000
## WAIS_GI -0.046 0.000
## WRAT -0.104 0.043 0.000
## PASAT 0.033 -0.080 -0.016 0.000
## WLGT -0.040 0.012 0.111 0.070 0.000
## copy_direct 0.125 -0.051 -0.057 0.012 -0.032 0.000
## copy_delayed 0.196 -0.024 -0.088 0.020 -0.019 0.000 0.000
## copy_immediate 0.193 -0.025 -0.090 0.022 -0.022 0.000 0.000 0.000
## CVLT 0.008 0.002 -0.004 0.057 0.064 0.032 0.137 0.127
## WCST 0.071 -0.022 -0.051 0.034 -0.020 0.101 0.059 0.059
## GPT_left 0.114 -0.051 -0.028 0.051 0.005 0.096 0.085 0.088
## GPT_right 0.117 -0.055 -0.031 0.066 0.020 0.102 0.066 0.060
## g_early 0.008 0.010 0.007 0.004 -0.030 -0.001 -0.014 -0.013
## CVLT WCST GPT_lf GPT_rg g_erly
## WAIS_BD
## WAIS_GI
## WRAT
## PASAT
## WLGT
## copy_direct
## copy_delayed
## copy_immediate
## CVLT 0.000
## WCST 0.009 0.000
## GPT_left -0.015 0.060 0.000
## GPT_right -0.005 0.058 0.000 0.000
## g_early -0.020 -0.004 -0.012 -0.013 0.000
##
## $mean
## WAIS_BD WAIS_GI WRAT PASAT WLGT
## 0 0 0 0 0
## copy_direct copy_delayed copy_immediate CVLT WCST
## 0 0 0 0 0
## GPT_left GPT_right g_early
## 0 0 0
#SEM comparisons
model_gains_1 = model_basic + "
Education ~ g_early
g_later ~ Education + g_early"
model_gains_2 = model_basic + "
Education ~ g_early
g_later ~ Education + g_early
#specific paths
WAIS_BD ~ Education
WAIS_GI ~ Education
WRAT ~ Education
PASAT ~ Education
copy_direct ~ Education
copy_delayed ~ Education
copy_immediate ~ Education
CVLT ~ Education
WCST ~ Education
GPT_left ~ Education
GPT_right ~ Education
"
model_gains_3 = model_basic + "
#g change
Education ~ g_early
g_later ~ g_early
#specific gains
WAIS_BD ~ Education
WAIS_GI ~ Education
WRAT ~ Education
PASAT ~ Education
copy_direct ~ Education
copy_delayed ~ Education
copy_immediate ~ Education
CVLT ~ Education
WCST ~ Education
GPT_left ~ Education
GPT_right ~ Education
"
model_gains_1b = model_basic2 + "
Education ~ g_early
g_later ~ Education + g_early
"
model_gains_2b = model_basic2 + "
Education ~ g_early
g_later ~ Education + g_early
#specific paths
WAIS_BD ~ Education
WAIS_GI ~ Education
WRAT ~ Education
PASAT ~ Education
copy_direct ~ Education
copy_delayed ~ Education
copy_immediate ~ Education
CVLT ~ Education
WCST ~ Education
GPT_left ~ Education
GPT_right ~ Education
"
model_gains_3b = model_basic2 + "
#g change
Education ~ g_early
g_later ~ g_early
#specific gains
WAIS_BD ~ Education
WAIS_GI ~ Education
WRAT ~ Education
PASAT ~ Education
copy_direct ~ Education
copy_delayed ~ Education
copy_immediate ~ Education
CVLT ~ Education
WCST ~ Education
GPT_left ~ Education
GPT_right ~ Education
"
gain_fits = list(
#with early g explicitly modeled
g_gains = sem(model_gains_1, data = d, std.ov = T, orthogonal = T),
gs_gains = sem(model_gains_2, data = d, std.ov = T, orthogonal = T),
s_gains = sem(model_gains_3, data = d, std.ov = T, orthogonal = T),
#without early g explicitly modeled
g_gains2 = sem(model_gains_1b, data = d, std.ov = T, orthogonal = T),
gs_gains2 = sem(model_gains_2b, data = d, std.ov = T, orthogonal = T),
s_gains2 = sem(model_gains_3b, data = d, std.ov = T, orthogonal = T)
)
#fit indexes
map(gain_fits, fitmeasures, fit.measures = fit_measures)
## $g_gains
## cfi gfi tli rmsea srmr aic
## 0.906 0.866 0.890 0.087 0.060 194334.969
##
## $gs_gains
## cfi gfi tli rmsea srmr aic
## 0.912 0.876 0.888 0.087 0.055 194051.740
##
## $s_gains
## cfi gfi tli rmsea srmr aic
## 0.911 0.875 0.888 0.087 0.055 194073.741
##
## $g_gains2
## cfi gfi tli rmsea srmr aic
## 0.93 0.95 0.92 0.08 0.06 143772.59
##
## $gs_gains2
## cfi gfi tli rmsea srmr aic
## 0.945 0.963 0.918 0.079 0.052 143440.921
##
## $s_gains2
## cfi gfi tli rmsea srmr aic
## 0.943 0.962 0.917 0.079 0.053 143493.260
#params
gain_fits$gs_gains2 %>% parameterestimates()
## lhs op rhs est se z pvalue ci.lower
## 1 g_later =~ WAIS_BD 1.000 0.000 NA NA 1.000
## 2 g_later =~ WAIS_GI 0.973 0.026 36.86 0.000 0.922
## 3 g_later =~ WRAT 0.983 0.027 36.19 0.000 0.930
## 4 g_later =~ PASAT 0.809 0.028 28.51 0.000 0.754
## 5 g_later =~ WLGT 0.654 0.027 23.99 0.000 0.601
## 6 g_later =~ copy_direct 0.637 0.028 22.59 0.000 0.582
## 7 g_later =~ copy_delayed 0.727 0.029 25.39 0.000 0.671
## 8 g_later =~ copy_immediate 0.713 0.028 25.04 0.000 0.657
## 9 g_later =~ CVLT 0.618 0.028 21.95 0.000 0.563
## 10 g_later =~ WCST 0.634 0.028 22.65 0.000 0.579
## 11 g_later =~ GPT_left 0.442 0.028 15.93 0.000 0.388
## 12 g_later =~ GPT_right 0.453 0.028 16.26 0.000 0.398
## 13 GPT_left ~~ GPT_right 0.543 0.016 33.35 0.000 0.511
## 14 copy_delayed ~~ copy_immediate 0.689 0.016 42.44 0.000 0.658
## 15 copy_direct ~~ copy_delayed 0.275 0.013 20.91 0.000 0.250
## 16 copy_direct ~~ copy_immediate 0.268 0.013 20.44 0.000 0.243
## 17 Education ~ g_early 0.548 0.013 43.10 0.000 0.524
## 18 g_later ~ Education 0.178 0.028 6.31 0.000 0.122
## 19 g_later ~ g_early 0.640 0.014 45.05 0.000 0.612
## 20 WAIS_BD ~ Education -0.250 0.032 -7.84 0.000 -0.312
## 21 WAIS_GI ~ Education 0.046 0.030 1.54 0.123 -0.012
## 22 WRAT ~ Education -0.006 0.030 -0.21 0.837 -0.065
## 23 PASAT ~ Education -0.122 0.028 -4.32 0.000 -0.178
## 24 copy_direct ~ Education -0.123 0.026 -4.74 0.000 -0.173
## 25 copy_delayed ~ Education -0.172 0.027 -6.32 0.000 -0.226
## 26 copy_immediate ~ Education -0.152 0.027 -5.62 0.000 -0.205
## 27 CVLT ~ Education -0.118 0.026 -4.61 0.000 -0.168
## 28 WCST ~ Education -0.091 0.026 -3.55 0.000 -0.142
## 29 GPT_left ~ Education -0.074 0.023 -3.18 0.001 -0.120
## 30 GPT_right ~ Education -0.101 0.024 -4.27 0.000 -0.147
## 31 WAIS_BD ~~ WAIS_BD 0.578 0.013 43.02 0.000 0.552
## 32 WAIS_GI ~~ WAIS_GI 0.360 0.009 41.02 0.000 0.343
## 33 WRAT ~~ WRAT 0.403 0.010 41.55 0.000 0.384
## 34 PASAT ~~ PASAT 0.681 0.015 44.61 0.000 0.651
## 35 WLGT ~~ WLGT 0.733 0.016 45.36 0.000 0.701
## 36 copy_direct ~~ copy_direct 0.814 0.018 45.51 0.000 0.779
## 37 copy_delayed ~~ copy_delayed 0.773 0.017 45.15 0.000 0.740
## 38 copy_immediate ~~ copy_immediate 0.774 0.017 45.20 0.000 0.741
## 39 CVLT ~~ CVLT 0.825 0.018 45.60 0.000 0.790
## 40 WCST ~~ WCST 0.802 0.018 45.52 0.000 0.768
## 41 GPT_left ~~ GPT_left 0.907 0.020 46.07 0.000 0.869
## 42 GPT_right ~~ GPT_right 0.910 0.020 46.05 0.000 0.871
## 43 Education ~~ Education 0.699 0.015 46.47 0.000 0.670
## 44 g_later ~~ g_later 0.057 0.004 14.06 0.000 0.049
## 45 g_early ~~ g_early 1.000 0.000 NA NA 1.000
## ci.upper
## 1 1.000
## 2 1.025
## 3 1.037
## 4 0.865
## 5 0.708
## 6 0.692
## 7 0.783
## 8 0.769
## 9 0.673
## 10 0.689
## 11 0.497
## 12 0.508
## 13 0.575
## 14 0.721
## 15 0.301
## 16 0.294
## 17 0.573
## 18 0.233
## 19 0.668
## 20 -0.187
## 21 0.104
## 22 0.053
## 23 -0.067
## 24 -0.072
## 25 -0.119
## 26 -0.099
## 27 -0.068
## 28 -0.041
## 29 -0.029
## 30 -0.055
## 31 0.605
## 32 0.377
## 33 0.422
## 34 0.711
## 35 0.765
## 36 0.849
## 37 0.807
## 38 0.808
## 39 0.861
## 40 0.837
## 41 0.946
## 42 0.949
## 43 0.729
## 44 0.065
## 45 1.000
lavaan_to_igraph = function(fit) {
#get params
params = parameterestimates(fit)
#subset to non-self
params$self = params$rhs == params$lhs
params = params[!params$self, ]
#unique nodes
unique_nodes = unique(c(params$rhs, params$lhs))
#make adjacency matrix
#init
adj_mat = matrix(0, ncol = length(unique_nodes), nrow = length(unique_nodes))
rownames(adj_mat) = colnames(adj_mat) = unique_nodes
#loop over rows and add
for (row_i in seq_along_rows(params)) {
row_ = params[row_i, ]
#latent regression
if (row_[["op"]] %in% c("=~")) {
adj_mat[row_[["lhs"]], row_[["rhs"]]] = 1
} else if (row_[["op"]] %in% c("~")) {
#observable regression
adj_mat[row_[["rhs"]], row_[["lhs"]]] = 1
} else if (row_[["op"]] %in% c("~~")) {
#covariance
adj_mat[row_[["rhs"]], row_[["lhs"]]] = 1
adj_mat[row_[["lhs"]], row_[["rhs"]]] = 1
}
}
#to igraph
igraph_ = igraph::graph_from_adjacency_matrix(adj_mat)
#add node info
browser()
igraph_
}
lavaan_to_igraph(gain_fits$gs_gains2) %>%
ggraph(layout = "treemap") +
geom_edge_fan() +
geom_node_point()
## Called from: lavaan_to_igraph(gain_fits$gs_gains2)
## debug at <text>#39: igraph_
## Multiple parents. Unfolding graph