# principles and practice of sem, 5th ed.
# rex b. kline, guilford press, 2023
# chapter 19, table 19.2, analysis 1
# partial sr model with a casual loop with
# data analyzed at the level of countries
# to avoid the problem that some R packages share the same name
# for different functions, all functions are specified next as
# package::function
# which prevents masking, or the default hiding of
# a function with a redundant name from a package used next
date()
v <- R.Version()
print(paste0(v$language, " version ", v$major, ".",
v$minor, " (", v$year, "-", v$month, "-", v$day, ")"))
library("lavaan")
library("semTools")
# get citations
citation(package = "lavaan", auto = TRUE)
citation(package = "semTools", auto = TRUE)
# input correlation matrix and
# standard deviations
robbinsLower.cor <- '
1.000
.933 1.000
.767 .738 1.000
.760 .737 .614 1.000
.820 .760 .664 .867 1.000
.454 .466 .372 .368 .375 1.000
.469 .480 .380 .457 .351 .498 1.000 '
robbins.cor <- lavaan::getCov(robbinsLower.cor, names = c("rule", "legal",
"corrupt", "bandwidth", "internet", "trust", "monarchy"))
robbins.cov <- lavaan::cor2cov(robbins.cor, sds = c(1.008,1.931,
1.424,2.585,1.569,.138,.394))
# display covariance matrix
robbins.cov
# maccallum-rmsea for whole model
# exact fit test
# power at N = 64
semTools::findRMSEApower(0, .05, 5, 64, .05, 1)
# minimum N for power at least .90
semTools::findRMSEAsamplesize(0, .05, 5, .90, .05, 1)
# in the orginal robbins model, the
# indicators of institutional quality
# were legal, rule, and corrupt, but
# the correlation between legal and rule is > .90
# so one indicator (rule) is dropped
robbins.model <- '
# common factors
InfoTech =~ bandwidth + internet
InstitQual =~ legal + corrupt
# structural model with causal loop,
# correlated disturbances, and instruments
InstitQual ~ trust + InfoTech
trust ~ InstitQual + monarchy
# correlated disturbances
InstitQual ~~ trust
# covariances between exogenous variables
monarchy ~~ InfoTech '
# fit model to data and display results
robbins <- lavaan::sem(robbins.model, sample.cov = robbins.cov,
sample.nobs = 64)
lavaan::summary(robbins, fit.measures = TRUE, standardized = TRUE,
rsquare = TRUE)
lavaan::standardizedSolution(robbins)
# implied covariance matrix
lavaan::fitted(robbins)
# implied covariance matrix for all variables (observed, latent)
lavaan::lavInspect(robbins, add.labels = TRUE, "cov.all")
# implied correlation matrix for all variables (observed, latent)
lavaan::lavInspect(robbins, add.labels = TRUE, "cor.all")
# residuals
lavaan::residuals(robbins, type = "raw")
lavaan::residuals(robbins, type = "standardized.mplus")
# bollen-type correlation residuals
# test statistic is crmr
lavaan::lavResiduals(robbins, type = "cor.bollen", summary = TRUE)
# bentler-type correlation residuals (same as bollen-type
# in this analysis)
# test statistic is srmr
lavaan::lavResiduals(robbins, type = "cor.bentler", summary = TRUE)