# principles and practice of sem, 5th ed.
# rex b. kline, guilford press, 2023
# chapter 8, table 8.1, analysis 1
# generate raw scores with descriptive statistics that
# exactly match those from the summarey data in
# table 4.3 for the the roth et al. (1989)
# parametric path model of illness
# 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(semTools)
library(lavaan)
# get citation information
citation("semTools", auto = TRUE)
citation("lavaan", auto = TRUE)
# variable order is exercise, hardy, fitness, stress, illness
# read and display roth correlation matrix
roth.cor <- matrix(c(1.00, -.03, .39, -.05, -.08,
-.03, 1.00, .07, -.23, -.16,
.39, .07, 1.00, -.13, -.29,
-.05, -.23, -.13, 1.00, .34,
-.08, -.16, -.29, .34, 1.00), ncol = 5, nrow = 5)
# read the standard deviations
roth.sd <- c(66.5, 38.0, 18.4, 33.5, 62.48)
# convert correlation matrix to covariance matrix and display
roth.cov <- diag(roth.sd) %*% roth.cor %*% diag(roth.sd)
# prepare to generate raw data where sample variances are
# calculated with df = N - 1 in the denominator, not N
c = 372/373
roth.cov = c * roth.cov
# generate raw scores
roth.data <- semTools::kd(roth.cov, 373, type = "exact")
# rename columns in data frame and display covariance matrix
names(roth.data) <- c("exercise", "hardy", "fitness", "stress", "illness")
var(roth.data)
# add variable means to all scores
# original mean for "hardy" is zero
# some generated raw scores are < 0 for "hardy,"
# but this does not matter for regression coefficients
# nor error variances
roth.data <- transform(roth.data, exercise = exercise + 40.9)
roth.data <- transform(roth.data, fitness = fitness + 67.1)
roth.data <- transform(roth.data, stress = stress + 24.0)
roth.data <- transform(roth.data, illness = illness + 71.67)
# display sample means
mean(roth.data$exercise)
mean(roth.data$hardy)
mean(roth.data$fitness)
mean(roth.data$stress)
mean(roth.data$illness)
# write data frame to external .csv file
# note that function semTools::kd() generates a different set of raw scores
# each time it is run, but they all have the same covariances
# and means
# ** IMPORTANT **
# change the path name listed next for your own computer to
# reproduce this analysis
# set working directory for writing the output file
setwd(file.path("C:", "Users", "rbkline", "Desktop"))
# show working directory
getwd()
write.csv(roth.data, "roth.csv", row.names = FALSE)