Two-Stage Path Analysis with Definition Variables Using OpenMx
tspa_mx_model.Rd
Fit a two-stage path analysis (2S-PA) model.
Arguments
- mx_model
A model object of class OpenMx::MxRAMModel, created by
OpenMx::mxModel()
or theumx
package. This is the structural model part.- data
A data frame containing factor scores.
- mat_ld
A \(p \times p\) matrix indicating the loadings of the factor scores on the latent variables. The ith row indicate loadings of the ith factor score variable on the latent variables. This could be one of the following:
A matrix created by
OpenMx::mxMatrix()
with loading values.A named numeric matrix, with rownames and column names matching the factor score and latent variables.
A named character matrix, with rownames and column names matching the factor score and latent variables, and the character values indicating the variable names in
data
for the corresponding loadings.
- mat_ev
Similar to
mat_ld
but for the error variance-covariance matrix of the factor scores.- mat_int
Similar to
mat_ld
but for the measurement intercept matrix of the factor scores.- fs_lv_names
A named character vector where each element is the name of a factor score variable, and the names of the vector are the corresponding name of the latent variables.
- ...
Additional arguments passed to
OpenMx::mxModel()
.
Value
An object of class OpenMx::MxModel. Note that the model has not been run.
Examples
library(mirt)
#> Loading required package: stats4
#> Loading required package: lattice
library(umx)
#> Loading required package: OpenMx
#> To take full advantage of multiple cores, use:
#> mxOption(key='Number of Threads', value=parallel::detectCores()) #now
#> Sys.setenv(OMP_NUM_THREADS=parallel::detectCores()) #before library(OpenMx)
#> For an overview type '?umx'
#>
#> Attaching package: ‘umx’
#> The following object is masked from ‘package:stats’:
#>
#> loadings
library(OpenMx)
# Simulate data with mirt
set.seed(1324)
num_obs <- 100
# Simulate theta
eta <- MASS::mvrnorm(num_obs, mu = c(0, 0), Sigma = diag(c(1, 1 - 0.5^2)),
empirical = TRUE)
th1 <- eta[, 1]
th2 <- -1 + 0.5 * th1 + eta[, 2]
# items and response data
a1 <- matrix(1, 10)
d1 <- matrix(rnorm(10))
a2 <- matrix(runif(10, min = 0.5, max = 1.5))
d2 <- matrix(rnorm(10))
dat1 <- mirt::simdata(a = a1, d = d1,
N = num_obs, itemtype = "2PL", Theta = th1)
dat2 <- mirt::simdata(a = a2, d = d2, N = num_obs,
itemtype = "2PL", Theta = th2)
# Factor scores
mod1 <- mirt(dat1, model = 1, itemtype = "Rasch", verbose = FALSE)
mod2 <- mirt(dat2, model = 1, itemtype = "2PL", verbose = FALSE)
fs1 <- fscores(mod1, full.scores.SE = TRUE)
fs2 <- fscores(mod2, full.scores.SE = TRUE)
# Combine factor scores and standard errors into data set
fs_dat <- as.data.frame(cbind(fs1, fs2))
names(fs_dat) <- c("fs1", "se_fs1", "fs2", "se_fs2")
# Compute reliability and error variances
fs_dat <- within(fs_dat, expr = {
rel_fs1 <- 1 - se_fs1^2
rel_fs2 <- 1 - se_fs2^2
ev_fs1 <- se_fs1^2 * (1 - se_fs1^2)
ev_fs2 <- se_fs2^2 * (1 - se_fs2^2)
})
# OpenMx model (from umx so that lavaan syntax can be used)
fsreg_umx <- umxLav2RAM(
"
fs2 ~ fs1
fs2 + fs1 ~ 1
",
printTab = FALSE)
#>
#> ?plot.MxModel options: std, means, digits, strip_zero, file, splines=T/F/ortho,..., min=, max =, same = , fixed, resid= 'circle|line|none'
# Prepare loading and error covariance matrices
cross_load <- matrix(c("rel_fs2", NA, NA, "rel_fs1"), nrow = 2) |>
`dimnames<-`(rep(list(c("fs2", "fs1")), 2))
err_cov <- matrix(c("ev_fs2", NA, NA, "ev_fs1"), nrow = 2) |>
`dimnames<-`(rep(list(c("fs2", "fs1")), 2))
# Create 2S-PA model (with definition variables)
tspa_mx <-
tspa_mx_model(fsreg_umx,
data = fs_dat,
mat_ld = cross_load,
mat_ev = err_cov
)
# Run OpenMx
tspa_mx_fit <- mxRun(tspa_mx)
#> Running 2SPAD with 5 parameters
# Summarize the results
summary(tspa_mx_fit)
#> Summary of 2SPAD
#>
#> free parameters:
#> name matrix row col Estimate Std.Error A
#> 1 fs1_to_fs2 m1.A fs2 fs1 0.526025404 0.2351855
#> 2 fs2_with_fs2 m1.S fs2 fs2 0.857316415 0.2253235
#> 3 fs1_with_fs1 m1.S fs1 fs1 0.541308628 0.1472492
#> 4 one_to_fs2 m1.M 1 fs2 -0.003189929 0.1234779
#> 5 one_to_fs1 m1.M 1 fs1 0.003287301 0.1002638
#>
#> Model Statistics:
#> | Parameters | Degrees of Freedom | Fit (-2lnL units)
#> Model: 5 395 453.4113
#> Saturated: NA NA NA
#> Independence: NA NA NA
#> Number of observations/statistics: 100/400
#>
#> Information Criteria:
#> | df Penalty | Parameters Penalty | Sample-Size Adjusted
#> AIC: -336.5887 463.4113 464.0496
#> BIC: -1365.6310 476.4371 460.6459
#> CFI: NA
#> TLI: 1 (also known as NNFI)
#> RMSEA: 0 [95% CI (NA, NA)]
#> Prob(RMSEA <= 0.05): NA
#> To get additional fit indices, see help(mxRefModels)
#> timestamp: 2024-09-06 04:15:37
#> Wall clock time: 0.152458 secs
#> optimizer: SLSQP
#> OpenMx version number: 2.21.12
#> Need help? See help(mxSummary)
#>