In OpenMx
, it is possible to specify a Structural Equation Model either by writing the entire matrices (with mxMatrix()
), or by writing only the paths (with mxPath()
). We will use the latter because it is faster to specify with longitudinal data, and usually more intuitive for researchers. First, install the package if necessary:
install.packages("OpenMx")
To build a model in OpenMx
, we use the function mxModel()
with the following arguments:
model
: Use model = "LCS_model"
to create a new model with named “LCS_model”.type
: Use type = RAM
(Reticular Action Model), to define the model in terms of single-headed and double-headed paths between variables, just as in a path diagram.manifestVars = c("Y1", "Y2", "Y3"...)
: Include the names of the observed variables in your database.latentVars = c("y1", "y2", "y3"...)
: Include the names that you will use to identify the latent variables in the model.mxData(observed = dfwide, type="raw")
: Select your database and indicate that it contains observed scores by setting the argument type to raw
(it is also possible to use covariance or correlation matrices as inputs).Once we have finished the preparations, building the model is very intuitive. All paths are defined through the function mxPath()
. The arguments from
and to
are used to indicate the origins and endings of the paths, arrows
to indicate regression (=1
) or covariance (=2
), free
to fix (=FALSE
) or freely estimate (=TRUE
) the parameters defining the paths, values
to indicate the value of a fixed parameter (when free=FALSE
) or to set to set an initial value for a free parameter (when free=TRUE
), and labels
to name the parameter defining the paths. Using the same label for multiple paths implies imposing an equality constraint, meaning that a single parameter will be estimated across those paths.
An important advantage of OpenMx
is that it does not require to define each single path separately. For example, it is possible to define all the paths from y(t - 1) to y(t) just by specifying from=latent_y[1:(t-1)], to=latent_y[2:t]
inside mxPath()
, where latent_y
is a string that contains the names of the latent states of y across all time points.
Obtain the example database here: Download LCSdata.txt
We will estimate the following model:
Step 1. Load the package and database:
library(OpenMx)
dfwide <- read.table("LCSdata.txt")
Step 2. Define the variables of the model:
Tmax <- 5 # Number of measurement occasions
colnames(dfwide) <- paste0("Y", 1:Tmax)
# Initial factor:
y0 <- "y0"
# Additive component:
ya <- "ya"
# Manifest scores:
manif_Y <- paste0("Y", 1:Tmax)
# Latent scores:
latent_y <- paste0("y", 1:Tmax)
# Latent changes:
change_y <- paste0("Delta_", 2:Tmax)
Step 3. Build the model:
LCS.model <- mxModel("Univariate LCS", type = "RAM",
manifestVars = manif_Y,
latentVars = c(y0, ya, latent_y, change_y),
mxData(observed = dfwide, type="raw"),
### LATENT STRUCTURE
# 1 -> Initial factor and additive component (means)
# “one” is used to define intercepts. In this case, the paths from “one” to y0 and ya represent the means of these latent variables.
mxPath(from="one", to=c(y0, ya),
arrows=1, free=TRUE, values= 0, labels=c("meany0", "meanya")),
# (Co)variances of the initial factor and additive component
mxPath(from=y0, arrows=2, free=TRUE, values=0, labels="vary0"),
mxPath(from=ya, arrows=2, free=TRUE, values=0, labels="varya"),
mxPath(from=y0, to=ya,
arrows=2, free=TRUE, values=0, labels="covy0ya"),
# Initial factor -> Initial latent score
mxPath(from=y0, to=latent_y[1], arrows=1, free=FALSE, values=1),
# Latent[t-1] -> Latent[t]
mxPath(from=latent_y[1:(Tmax-1)], to=latent_y[2:Tmax],
arrows=1, free=FALSE, values=1),
# Additive component -> Change[t] (alpha = 1)
mxPath(from=ya, to=change_y, arrows=1, free=FALSE, values=1),
# Latent[t-1] -> Change[t] (self-feedback)
mxPath(from=latent_y[1:(Tmax-1)], to=change_y,
arrows=1, free=TRUE, values=0, labels="beta"),
# Change -> Latent
mxPath(from=change_y, to=latent_y[2:Tmax], arrows=1, free=FALSE, values=1),
### MEASUREMENT STRUCTURE
# Latent -> Manifest
mxPath(from=latent_y, to=manif_Y, arrows=1, free=FALSE, values=1),
# Measurement error variance
mxPath(from=manif_Y, arrows=2, free=TRUE, values=.5, labels="merY"))
Step 4. Estimate the model parameters:
LCS.fit <- mxRun(LCS.model)
Click here to see the results
summary(LCS.fit)
## Summary of Univariate LCS
##
## free parameters:
## name matrix row col Estimate Std.Error A
## 1 beta A Delta_2 y1 -0.23438720 0.010998162
## 2 merY S Y1 Y1 0.32064158 0.005884500
## 3 vary0 S y0 y0 0.64509081 0.028010421
## 4 covy0ya S y0 ya 0.11723448 0.009873330
## 5 varya S ya ya 0.09966682 0.006198747
## 6 meany0 M 1 y0 -1.15984663 0.021784269
## 7 meanya M 1 ya -0.94513129 0.023805748
##
## Model Statistics:
## | Parameters | Degrees of Freedom | Fit (-2lnL units)
## Model: 7 9893 23280.07
## Saturated: 20 9880 NA
## Independence: 10 9890 NA
## Number of observations/statistics: 1980/9900
##
## Information Criteria:
## | df Penalty | Parameters Penalty | Sample-Size Adjusted
## AIC: 3494.069 23294.07 23294.13
## BIC: -51816.231 23333.20 23310.97
## To get additional fit indices, see help(mxRefModels)
## timestamp: 2021-04-18 20:26:58
## Wall clock time: 0.1585219 secs
## optimizer: SLSQP
## OpenMx version number: 2.19.1
## Need help? See help(mxSummary)
It is possible to extend the previous model to include innovation variance by just adding a new mxPath()
to the already built LCS.model
:
stoch_LCS.model <- mxModel(LCS.model, # call the previous model
# Dynamic error variance
mxPath(from=change_y, arrows=2, free=TRUE, values=0, labels="derY"))
# Run the new model:
stoch_LCS.fit <- mxRun(stoch_LCS.model)
Click here to see the results
summary(stoch_LCS.fit)
## Summary of Univariate LCS
##
## free parameters:
## name matrix row col Estimate Std.Error A
## 1 beta A Delta_2 y1 -0.23978246 0.011700562
## 2 merY S Y1 Y1 0.26099004 0.011663449
## 3 vary0 S y0 y0 0.66218447 0.028157304
## 4 covy0ya S y0 ya 0.11338030 0.010260152
## 5 varya S ya ya 0.08076624 0.007491957
## 6 derY S Delta_2 Delta_2 0.10208647 0.018716374
## 7 meany0 M 1 y0 -1.15671290 0.021407325
## 8 meanya M 1 ya -0.95608397 0.025150281
##
## Model Statistics:
## | Parameters | Degrees of Freedom | Fit (-2lnL units)
## Model: 8 9892 23247.73
## Saturated: 20 9880 NA
## Independence: 10 9890 NA
## Number of observations/statistics: 1980/9900
##
## Information Criteria:
## | df Penalty | Parameters Penalty | Sample-Size Adjusted
## AIC: 3463.733 23263.73 23263.81
## BIC: -51840.976 23308.46 23283.04
## To get additional fit indices, see help(mxRefModels)
## timestamp: 2021-04-18 20:26:58
## Wall clock time: 0.1607468 secs
## optimizer: SLSQP
## OpenMx version number: 2.19.1
## Need help? See help(mxSummary)
Obtain the example database here: Download MILCSdata.txt
We will estimate the following model:
Step 1. Load the package and database:
library(OpenMx)
dfwide <- read.table("MILCSdata.txt")
Step 2. Define the variables of the model:
Tmax <- 5 # Number of measurement occasions
# Create the labels for the latent state at t=0, the additive component, each one of the observed indicators, the latent scores, and the latent changes:
y0 <- "y0"
ya <- "ya"
indic_Y1 <- paste0("Y1_t", 1:Tmax)
indic_Y2 <- paste0("Y2_t", 1:Tmax)
indic_Y3 <- paste0("Y3_t", 1:Tmax)
latent_y <- paste0("y", 1:Tmax)
change_y <- paste0("Delta_", 2:Tmax)
Step 3. Build the model:
MI_LCS.model <- mxModel("Multiple Indicator LCS", type = "RAM",
manifestVars = c(indic_Y1, indic_Y2, indic_Y3),
latentVars = c(y0, ya, latent_y, change_y),
mxData(observed = dfwide, type="raw"),
### LATENT STRUCTURE
# 1 -> Initial factors and additive components (means)
# Note that we only estimate the latent mean of the additive component
mxPath(from="one", to=ya, arrows=1, free=TRUE, values= 0, labels="meanya"),
# (Co)variances of the initial factors and additive components (covariance structure)
mxPath(from=y0, arrows=2, free=TRUE, values=0, labels="vary0"),
mxPath(from=ya, arrows=2, free=TRUE, values=0, labels="varya"),
mxPath(from=y0, to=ya,
arrows=2, free=TRUE, values=0, labels="covy0ya"),
# Initial factor -> Initial latent score
mxPath(from=y0, to=latent_y[1], arrows=1, free=FALSE, values=1),
# Latent[t-1] -> Latent[t]
mxPath(from=latent_y[1:(Tmax-1)], to=latent_y[2:Tmax],
arrows=1, free=FALSE, values=1),
# Additive component -> Change (alpha = 1)
mxPath(from=ya, to=change_y, arrows=1, free=FALSE, values=1),
# Latent[t-1] -> Change[t] (self-feedback)
mxPath(from=latent_y[1:(Tmax-1)], to=change_y,
arrows=1, free=TRUE, values=0, labels="beta"),
# Change -> Latent
mxPath(from=change_y, to=latent_y[2:Tmax], arrows=1, free=FALSE, values=1),
## For the stochastic version, include:
# Dynamic error variance (time-invariant)
mxPath(from=change_y, arrows=2, free=TRUE, values=0, labels="derY"),
### MEASUREMENT STRUCTURE
# Factor loadings: Configural and weak invariance
mxPath(from=latent_y, to=indic_Y1, arrows=1, free=FALSE, values=1, labels="lambda_Y1"),
mxPath(from=latent_y, to=indic_Y2, arrows=1, free=TRUE, values=0, labels="lambda_Y2"),
mxPath(from=latent_y, to=indic_Y3, arrows=1, free=TRUE, values=0, labels="lambda_Y3"),
# Intercepts of the indicators: Strong invariance
mxPath(from="one", to=indic_Y1, arrows=1, free=TRUE, values=0, labels="tau_Y1"),
mxPath(from="one", to=indic_Y2, arrows=1, free=TRUE, values=0, labels="tau_Y2"),
mxPath(from="one", to=indic_Y3, arrows=1, free=TRUE, values=0, labels="tau_Y3"),
# Measurement error variances (time-invariant)
mxPath(from=indic_Y1, arrows=2, free=TRUE, values=0, labels="mer_Y1"),
mxPath(from=indic_Y2, arrows=2, free=TRUE, values=0, labels="mer_Y2"),
mxPath(from=indic_Y3, arrows=2, free=TRUE, values=0, labels="mer_Y3"))
Step 4. Estimate the model parameters:
MI_LCS.fit <- mxRun(MI_LCS.model)
Click here to see the results
summary(MI_LCS.fit)
## Summary of Multiple Indicator LCS
##
## free parameters:
## name matrix row col Estimate Std.Error A
## 1 lambda_Y2 A Y2_t1 y1 0.84634200 0.004091916
## 2 lambda_Y3 A Y3_t1 y1 0.74303404 0.004770838
## 3 beta A Delta_2 y1 -0.24632391 0.007184629
## 4 mer_Y1 S Y1_t1 Y1_t1 0.19487428 0.004155686
## 5 mer_Y2 S Y2_t1 Y2_t1 0.15173228 0.003107957
## 6 mer_Y3 S Y3_t1 Y3_t1 0.29966754 0.004820008
## 7 vary0 S y0 y0 0.66414861 0.023782085
## 8 covy0ya S y0 ya 0.11515411 0.008738750
## 9 varya S ya ya 0.08409004 0.006192244
## 10 derY S Delta_2 Delta_2 0.20116269 0.006812258
## 11 tau_Y1 M 1 Y1_t1 -0.43804148 0.020069374
## 12 tau_Y2 M 1 Y2_t1 -0.38346417 0.017065635
## 13 tau_Y3 M 1 Y3_t1 -0.34571808 0.016311434
## 14 meanya M 1 ya -0.96908182 0.012776444
##
## Model Statistics:
## | Parameters | Degrees of Freedom | Fit (-2lnL units)
## Model: 14 29686 53918.5
## Saturated: 135 29565 NA
## Independence: 30 29670 NA
## Number of observations/statistics: 1980/29700
##
## Information Criteria:
## | df Penalty | Parameters Penalty | Sample-Size Adjusted
## AIC: -5453.495 53946.50 53946.72
## BIC: -171423.531 54024.78 53980.30
## To get additional fit indices, see help(mxRefModels)
## timestamp: 2021-04-18 20:26:59
## Wall clock time: 0.221652 secs
## optimizer: SLSQP
## OpenMx version number: 2.19.1
## Need help? See help(mxSummary)
Obtain the example database here: Download BLCSdata.txt
We will estimate the following model:
Step 1. Load the package and database:
library(OpenMx)
dfwide <- read.table("BLCSdata.txt")
Step 2. Define the variables of the model:
Tmax <- 5 # Number of measurement occasions
colnames(dfwide) <- c(paste0("X", 1:Tmax), paste0("Y",1:Tmax))
# Create the labels for the latent state at t=0, the additive component, the manifest scores, their corresponding latent scores, and the latent changes:
x0 <- "x0"
xa <- "xa"
y0 <- "y0"
ya <- "ya"
manif_X <- paste0("X", 1:Tmax)
manif_Y <- paste0("Y", 1:Tmax)
latent_x <- paste0("x", 1:Tmax)
latent_y <- paste0("y", 1:Tmax)
change_x <- paste0("Delta_x", 2:Tmax)
change_y <- paste0("Delta_y", 2:Tmax)
Step 3. Build the model:
BLCS.model <- mxModel("Bivariate LCS", type="RAM",
manifestVars=c(manif_Y, manif_X),
latentVars=c(x0, xa, y0, ya, latent_x, latent_y, change_x, change_y),
mxData(observed = dfwide, type="raw"),
### LATENT STRUCTURE
# 1 -> Initial factors and additive components (means)
mxPath(from="one", to=c(x0, xa, y0, ya),
arrows=1, free=TRUE, values= 0, labels=c("meanx0", "meanxa", "meany0", "meanya")),
# (Co)variances of the initial factors and additive components
mxPath(from="x0", arrows=2, free=TRUE, values=0, labels="varx0"),
mxPath(from="xa", arrows=2, free=TRUE, values=0, labels="varxa"),
mxPath(from="y0", arrows=2, free=TRUE, values=0, labels="vary0"),
mxPath(from="ya", arrows=2, free=TRUE, values=0, labels="varya"),
mxPath(from="x0", to="y0", arrows=2, free=TRUE, values=0, labels="covx0y0"),
mxPath(from="x0", to="xa", arrows=2, free=TRUE, values=0, labels="covx0xa"),
mxPath(from="x0", to="ya", arrows=2, free=TRUE, values=0, labels="covx0ya"),
mxPath(from="xa", to="y0", arrows=2, free=TRUE, values=0, labels="covxay0"),
mxPath(from="xa", to="ya", arrows=2, free=TRUE, values=0, labels="covxaya"),
mxPath(from="y0", to="ya", arrows=2, free=TRUE, values=0, labels="covy0ya"),
# Initial factor -> Initial latent score
mxPath(from=x0, to=latent_x[1], arrows=1, free=FALSE, values=1),
mxPath(from=y0, to=latent_y[1], arrows=1, free=FALSE, values=1),
# Latent[t-1] -> Latent[t]
mxPath(from=latent_x[1:(Tmax-1)], to=latent_x[2:Tmax], arrows=1, free=FALSE, values=1),
mxPath(from=latent_y[1:(Tmax-1)], to=latent_y[2:Tmax], arrows=1, free=FALSE, values=1),
# Additive component -> Change (alpha = 1)
mxPath(from=xa, to=change_x, arrows=1, free=FALSE, values=1),
mxPath(from=ya, to=change_y, arrows=1, free=FALSE, values=1),
# Latent[t-1] -> Change[t] (self-feedbacks)
mxPath(from=latent_x[1:(Tmax-1)], to=change_x, arrows=1, free=TRUE, values=0, labels="beta_x"),
mxPath(from=latent_y[1:(Tmax-1)], to=change_y, arrows=1, free=TRUE, values=0, labels="beta_y"),
# Latent[t-1] -> Change[t] (couplings)
mxPath(from=latent_x[1:(Tmax-1)], to=change_y, arrows=1, free=TRUE, values=0, labels="gamma_y"),
mxPath(from=latent_y[1:(Tmax-1)], to=change_x, arrows=1, free=TRUE, values=0, labels="gamma_x"),
# Change -> Latent
mxPath(from=change_x, to=latent_x[2:Tmax], arrows=1, free=FALSE, values=1),
mxPath(from=change_y, to=latent_y[2:Tmax], arrows=1, free=FALSE, values=1),
### MEASUREMENT STRUCTURE
# Latent -> Manifest
mxPath(from=c(latent_x, latent_y), to=c(manif_X, manif_Y), arrows=1, free=FALSE, values=1),
# Measurement errors variances and covariance
mxPath(from=manif_X, arrows=2, free=TRUE, values=.5, labels="merX"),
mxPath(from=manif_Y, arrows=2, free=TRUE, values=.5, labels="merY"),
mxPath(from=manif_X, to=manif_X, arrows=2, free=TRUE, values=0, labels="covMer"))
Step 4. Estimate the model parameters:
BLCS.fit <- mxRun(BLCS.model)
Click here to see the results
summary(BLCS.fit)
## Summary of Bivariate LCS
##
## free parameters:
## name matrix row col Estimate Std.Error A
## 1 beta_x A Delta_x2 x1 0.37494095 0.012214135
## 2 gamma_y A Delta_y2 x1 -0.57279026 0.007822497
## 3 gamma_x A Delta_x2 y1 0.78274382 0.021090686
## 4 beta_y A Delta_y2 y1 -0.75220638 0.013225624
## 5 merY S Y1 Y1 0.28303669 0.005158571
## 6 covMer S X1 X1 0.37445849 0.007154220
## 7 varx0 S x0 x0 0.59738523 0.024795487
## 8 covx0xa S x0 xa -0.08172970 0.012532978
## 9 varxa S xa xa 0.25189317 0.013453275
## 10 covx0y0 S x0 y0 -0.09318767 0.014853277
## 11 covxay0 S xa y0 -0.08437976 0.010850833
## 12 vary0 S y0 y0 0.32163704 0.017177964
## 13 covx0ya S x0 ya 0.13963737 0.015606761
## 14 covxaya S xa ya 0.07196516 0.014304371
## 15 covy0ya S y0 ya 0.12871606 0.011974518
## 16 varya S ya ya 0.37146990 0.020059356
## 17 meanx0 M 1 x0 -1.04563007 0.021005908
## 18 meanxa M 1 xa -3.05760316 0.073351150
## 19 meany0 M 1 y0 3.36771530 0.017298754
## 20 meanya M 1 ya 2.48788716 0.047705826
##
## Model Statistics:
## | Parameters | Degrees of Freedom | Fit (-2lnL units)
## Model: 20 19780 50033.75
## Saturated: 65 19735 NA
## Independence: 20 19780 NA
## Number of observations/statistics: 1980/19800
##
## Information Criteria:
## | df Penalty | Parameters Penalty | Sample-Size Adjusted
## AIC: 10473.75 50073.75 50074.18
## BIC: -100113.30 50185.57 50122.03
## To get additional fit indices, see help(mxRefModels)
## timestamp: 2021-04-18 20:27:00
## Wall clock time: 0.433033 secs
## optimizer: SLSQP
## OpenMx version number: 2.19.1
## Need help? See help(mxSummary)
It is possible to extend the previous model to include innovation variances and covariance by just adding a new mxPath() to the already built BLCS.model:
stoch_BLCS.model <- mxModel(BLCS.model, # call the previous model
# Dynamic error variances and covariance
mxPath(from=change_x, arrows=2, free=TRUE, values=0, labels="derX"),
mxPath(from=change_y, arrows=2, free=TRUE, values=0, labels="derY"),
mxPath(from=change_x, to=change_y, arrows=2, free=TRUE, values=0, labels="covDer"))
# Run the new model:
stoch_BLCS.fit <- mxRun(stoch_BLCS.model)
Click here to see the results
summary(stoch_BLCS.fit)
## Summary of Bivariate LCS
##
## free parameters:
## name matrix row col Estimate Std.Error A
## 1 beta_x A Delta_x2 x1 0.60288269 0.009715951
## 2 gamma_y A Delta_y2 x1 -0.24578344 0.006208989
## 3 gamma_x A Delta_x2 y1 0.95441632 0.018624155
## 4 beta_y A Delta_y2 y1 -0.39203653 0.012596048
## 5 merY S Y1 Y1 0.04548341 0.010143332
## 6 covMer S X1 X1 0.29555760 0.009483033
## 7 varx0 S x0 x0 0.61531651 0.024740008
## 8 covx0xa S x0 xa -0.18999044 0.015137135
## 9 varxa S xa xa 0.17806823 0.014258193
## 10 covx0y0 S x0 y0 -0.13762347 0.014417543
## 11 covxay0 S xa y0 -0.20543079 0.011616959
## 12 vary0 S y0 y0 0.45751709 0.018976062
## 13 covx0ya S x0 ya 0.03441336 0.006431347
## 14 covxaya S xa ya -0.11828754 0.005188054
## 15 covy0ya S y0 ya 0.03139110 0.005913824
## 16 varya S ya ya -0.06319358 0.006256364
## 17 derX S Delta_x2 Delta_x2 0.39226419 0.033374137
## 18 covDer S Delta_x2 Delta_y2 0.27089696 0.012865807
## 19 derY S Delta_y2 Delta_y2 0.48102413 0.021078158
## 20 meanx0 M 1 x0 -1.06660642 0.020642608
## 21 meanxa M 1 xa -3.32498894 0.072773121
## 22 meany0 M 1 y0 3.31622793 0.015933272
## 23 meanya M 1 ya 1.67278454 0.048363686
##
## Model Statistics:
## | Parameters | Degrees of Freedom | Fit (-2lnL units)
## Model: 23 19777 48893.06
## Saturated: 65 19735 NA
## Independence: 20 19780 NA
## Number of observations/statistics: 1980/19800
##
## Information Criteria:
## | df Penalty | Parameters Penalty | Sample-Size Adjusted
## AIC: 9339.064 48939.06 48939.63
## BIC: -101231.218 49067.65 48994.58
## To get additional fit indices, see help(mxRefModels)
## timestamp: 2021-04-18 20:27:01
## Wall clock time: 0.5549529 secs
## optimizer: SLSQP
## OpenMx version number: 2.19.1
## Need help? See help(mxSummary)
Obtain the example database here: Download MIBLCSdata.txt
We will estimate the following model:
Step 1. Load the package and database:
library(OpenMx)
dfwide <- read.table("MIBLCSdata.txt")
Step 2. Define the variables of the model:
Tmax <- 5 # Number of measurement occasions
# Variables
x0 <- "x0"
xa <- "xa"
y0 <- "y0"
ya <- "ya"
indic_X1 <- paste0("X1_t", 1:Tmax)
indic_X2 <- paste0("X2_t", 1:Tmax)
indic_Y1 <- paste0("Y1_t", 1:Tmax)
indic_Y2 <- paste0("Y2_t", 1:Tmax)
indic_Y3 <- paste0("Y3_t", 1:Tmax)
latent_x <- paste0("x", 1:Tmax)
latent_y <- paste0("y", 1:Tmax)
change_x <- paste0("Delta_x", 2:Tmax)
change_y <- paste0("Delta_y", 2:Tmax)
Step 3. Build the model:
MI_BLCS.model <- mxModel("Bivariate LCS", type="RAM",
manifestVars=c(indic_X1, indic_X2, indic_Y1, indic_Y2, indic_Y3),
latentVars=c(x0, xa, y0, ya, latent_x, latent_y, change_x, change_y),
mxData(observed = dfwide, type="raw"),
### LATENT STRUCTURE
# 1 -> Initial factors and additive components (means)
mxPath(from="one", to=c(xa, ya),
arrows=1, free=TRUE, values= 0, labels=c("meanxa", "meanya")),
# Covariance structure of the latent initial conditions
mxPath(from="x0", arrows=2, free=TRUE, values=0, labels="varx0"),
mxPath(from="xa", arrows=2, free=TRUE, values=0, labels="varxa"),
mxPath(from="y0", arrows=2, free=TRUE, values=0, labels="vary0"),
mxPath(from="ya", arrows=2, free=TRUE, values=0, labels="varya"),
mxPath(from="x0", to="y0", arrows=2, free=TRUE, values=0, labels="covx0y0"),
mxPath(from="x0", to="xa", arrows=2, free=TRUE, values=0, labels="covx0xa"),
mxPath(from="x0", to="ya", arrows=2, free=TRUE, values=0, labels="covx0ya"),
mxPath(from="xa", to="y0", arrows=2, free=TRUE, values=0, labels="covxay0"),
mxPath(from="xa", to="ya", arrows=2, free=TRUE, values=0, labels="covxaya"),
mxPath(from="y0", to="ya", arrows=2, free=TRUE, values=0, labels="covy0ya"),
# Initial factor -> Initial latent score
mxPath(from=x0, to=latent_x[1], arrows=1, free=FALSE, values=1),
mxPath(from=y0, to=latent_y[1], arrows=1, free=FALSE, values=1),
# Latent[t-1] -> Latent[t]
mxPath(from=latent_x[1:(Tmax-1)], to=latent_x[2:Tmax], arrows=1, free=FALSE, values=1),
mxPath(from=latent_y[1:(Tmax-1)], to=latent_y[2:Tmax], arrows=1, free=FALSE, values=1),
# Additive component -> Change (alpha = 1)
mxPath(from=xa, to=change_x, arrows=1, free=FALSE, values=1),
mxPath(from=ya, to=change_y, arrows=1, free=FALSE, values=1),
# Latent[t-1] -> Change[t] (self-feedbacks)
mxPath(from=latent_x[1:(Tmax-1)], to=change_x, arrows=1, free=TRUE, values=0, labels="beta_x"),
mxPath(from=latent_y[1:(Tmax-1)], to=change_y, arrows=1, free=TRUE, values=0, labels="beta_y"),
# Latent[t-1] -> Change[t] (couplings)
mxPath(from=latent_x[1:(Tmax-1)], to=change_y, arrows=1, free=TRUE, values=0, labels="gamma_y"),
mxPath(from=latent_y[1:(Tmax-1)], to=change_x, arrows=1, free=TRUE, values=0, labels="gamma_x"),
# Change -> Latent
mxPath(from=change_x, to=latent_x[2:Tmax], arrows=1, free=FALSE, values=1),
mxPath(from=change_y, to=latent_y[2:Tmax], arrows=1, free=FALSE, values=1),
## For the stochastic version, include:
# Dynamic error variances and covariance (time-invariant)
mxPath(from=change_x, arrows=2, free=TRUE, values=0, labels="derX"),
mxPath(from=change_y, arrows=2, free=TRUE, values=0, labels="derY"),
mxPath(from=change_x, to=change_y, arrows=2, free=TRUE, values=0, labels="covDer"),
## MEASUREMENT STRUCTURE
# Factor loadings: Configural and weak invariance
mxPath(from=latent_x, to=indic_X1, arrows=1, free=FALSE, values=1, labels="lambda_X1"),
mxPath(from=latent_x, to=indic_X2, arrows=1, free=TRUE, values=0, labels="lambda_X2"),
mxPath(from=latent_y, to=indic_Y1, arrows=1, free=FALSE, values=1, labels="lambda_Y1"),
mxPath(from=latent_y, to=indic_Y2, arrows=1, free=TRUE, values=0, labels="lambda_Y2"),
mxPath(from=latent_y, to=indic_Y3, arrows=1, free=TRUE, values=0, labels="lambda_Y3"),
# Intercepts of the indicators: Strong invariance
mxPath(from="one", to=indic_X1, arrows=1, free=TRUE, values=0, labels="tau_X1"),
mxPath(from="one", to=indic_X2, arrows=1, free=TRUE, values=0, labels="tau_X2"),
mxPath(from="one", to=indic_Y1, arrows=1, free=TRUE, values=0, labels="tau_Y1"),
mxPath(from="one", to=indic_Y2, arrows=1, free=TRUE, values=0, labels="tau_Y2"),
mxPath(from="one", to=indic_Y3, arrows=1, free=TRUE, values=0, labels="tau_Y3"),
# Measurement error variances (time-invariant)
mxPath(from=indic_X1, arrows=2, free=TRUE, values=0, labels="mer_X1"),
mxPath(from=indic_X2, arrows=2, free=TRUE, values=0, labels="mer_X2"),
mxPath(from=indic_Y1, arrows=2, free=TRUE, values=0, labels="mer_Y1"),
mxPath(from=indic_Y2, arrows=2, free=TRUE, values=0, labels="mer_Y2"),
mxPath(from=indic_Y3, arrows=2, free=TRUE, values=0, labels="mer_Y3")
)
Step 4. Estimate the model parameters:
MI_BLCS.fit <- mxRun(MI_BLCS.model)
Click here to see the results
summary(MI_BLCS.fit)
## Summary of Bivariate LCS
##
## free parameters:
## name matrix row col Estimate Std.Error A
## 1 lambda_X2 A X2_t1 x1 0.90046698 0.001748088
## 2 beta_x A Delta_x2 x1 0.35445677 0.008555211
## 3 gamma_y A Delta_y2 x1 -0.54843332 0.006541111
## 4 lambda_Y2 A Y2_t1 y1 0.85028627 0.001980699
## 5 lambda_Y3 A Y3_t1 y1 0.74700598 0.002464167
## 6 gamma_x A Delta_x2 y1 0.64372718 0.008413555
## 7 beta_y A Delta_y2 y1 -0.74664977 0.006348337
## 8 mer_X1 S X1_t1 X1_t1 0.19596694 0.004017893
## 9 mer_X2 S X2_t1 X2_t1 0.14597864 0.003124073
## 10 mer_Y1 S Y1_t1 Y1_t1 0.24607402 0.004516764
## 11 mer_Y2 S Y2_t1 Y2_t1 0.09962459 0.002372177
## 12 mer_Y3 S Y3_t1 Y3_t1 0.29526091 0.004673245
## 13 varx0 S x0 x0 0.60023545 0.021157471
## 14 covx0xa S x0 xa -0.12542800 0.011056446
## 15 varxa S xa xa 0.23584393 0.011767043
## 16 covx0y0 S x0 y0 -0.10151284 0.012587120
## 17 covxay0 S xa y0 -0.09604707 0.008997802
## 18 vary0 S y0 y0 0.38401310 0.014522304
## 19 covx0ya S x0 ya 0.15296666 0.012578506
## 20 covxaya S xa ya 0.09407315 0.011474081
## 21 covy0ya S y0 ya 0.13885946 0.010102650
## 22 varya S ya ya 0.33345988 0.016930950
## 23 derX S Delta_x2 Delta_x2 0.20042123 0.009299487
## 24 covDer S Delta_x2 Delta_y2 0.02598560 0.004831832
## 25 derY S Delta_y2 Delta_y2 0.14808508 0.005028817
## 26 tau_X1 M 1 X1_t1 -0.55146672 0.019248658
## 27 tau_X2 M 1 X2_t1 -0.48769254 0.017242585
## 28 tau_Y1 M 1 Y1_t1 1.28709245 0.016988246
## 29 tau_Y2 M 1 Y2_t1 1.10167744 0.013509374
## 30 tau_Y3 M 1 Y3_t1 0.98877077 0.014625937
## 31 meanxa M 1 xa -2.55366868 0.015082660
## 32 meanya M 1 ya 2.55835593 0.016196764
##
## Model Statistics:
## | Parameters | Degrees of Freedom | Fit (-2lnL units)
## Model: 32 49468 90302.35
## Saturated: 350 49150 NA
## Independence: 50 49450 NA
## Number of observations/statistics: 1980/49500
##
## Information Criteria:
## | df Penalty | Parameters Penalty | Sample-Size Adjusted
## AIC: -8633.652 90366.35 90367.43
## BIC: -285201.925 90545.26 90443.59
## To get additional fit indices, see help(mxRefModels)
## timestamp: 2021-04-18 20:27:04
## Wall clock time: 2.345692 secs
## optimizer: SLSQP
## OpenMx version number: 2.19.1
## Need help? See help(mxSummary)