How to specify a random intercept cross-lagged panel model in OpenMx?
I am trying to specify an RI-CLPM in OpenMx. However, if I constrain the variance of the observed indicators to zero, the model implied covariance matrix is not positive definite - but these variances are supposed to be zero, as they are partialized into a time-invariant component and a time-variant component. E.g., the variance x1 <-> x1 should be split up into RIx <-> RIx and cx1 <-> cx1.
Can anyone help me correctly specify this model in OpenMx?
df <- data.frame(matrix(rnorm(500*8), ncol = 8))
names(df) <- paste0(rep(c("x", "y"), each = 4), 1:4)
xobs <- grep("^x", names(df), value = TRUE)
yobs <- grep("^y", names(df), value = TRUE)
xvars <- paste0("c", grep("^x", names(df), value = TRUE))
yvars <- paste0("c", grep("^y", names(df), value = TRUE))
xminone <- xvars[-1]
xminend <- xvars[-length(xvars)]
yminone <- yvars[-1]
yminend <- yvars[-length(yvars)]
riclpm<-mxModel("riclpm",
type="RAM",
manifestVars=c(xobs, yobs),
latentVars = c("RIx", "RIy", xvars, yvars),
mxData(observed=df, type="raw"),
mxPath(from="RIx", to=xobs, arrows=1, free=FALSE, values=1),
mxPath(from="RIy", to=yobs, arrows=1, free=FALSE, values=1),
mxPath(from=xvars, to=xobs, arrows=1, free=FALSE, values=1),
mxPath(from=yvars, to=yobs, arrows=1, free=FALSE, values=1),
# RI cors
mxPath(from="RIy", to="RIx", arrows=2, free=TRUE, values=0),
mxPath(from=c("RIy", "RIx"), arrows=2, free=TRUE, values=0),
mxPath(from=xminend, to=xminone, arrows=1, free=TRUE, values=c(.1), labels="x_x"),
mxPath(from=yminend, to=yminone, arrows=1, free=TRUE, values=c(.1), labels="y_y"),
mxPath(from=xminend, to=yminone, arrows=1, free=TRUE, values=c(.1), labels="y_x"),
mxPath(from=yminend, to=xminone, arrows=1, free=TRUE, values=c(.1), labels="x_y"),
# Vars
mxPath(from=xvars[1], arrows=2, free=TRUE, values=c(.1), labels = "vx1"),
mxPath(from=yvars[1], arrows=2, free=TRUE, values=c(.1), labels = "vy1"),
mxPath(from=xminone, arrows=2, free=TRUE, values=c(.1), labels = "vx"),
mxPath(from=yminone, arrows=2, free=TRUE, values=c(.1), labels = "vy"),
#mxPath(from=c(xobs, yobs), arrows=2, free=TRUE, values=c(.1)),
mxPath(from=c(xobs, yobs), arrows=2, free=FALSE, values=0),
# Covars
mxPath(from=xvars[1], to = yvars[1], arrows=2, free=TRUE, values=0, labels = "rxy1"),
mxPath(from=xminone, to = yminone, arrows=2, free=TRUE, values=0, labels = "rxy"),
mxPath(from = 'one', to = c(xvars, yvars))
)
res <- mxRun(riclpm)
Forgot variances of RIx and RIy?
require(umx)
plot(riclpm)
It looked like you set the variances of `RIx` and `RIy` to zero. So, I added
mxPath(c('RIx', 'RIy'), arrows=2, values=1.5),
into your model and it ran, only giving a warning about the Hessian being non-positive definite (probably because the data were nonsense).
Does that help?
Log in or register to post comments
Dear mhunter, thank you! My
mxPath(from=c("RIy", "RIx"), arrows=2, free=TRUE, values=0)
If I set this to
mxPath(from=c("RIy", "RIx"), arrows=2, free=TRUE, values=1.5)
I indeed also get the error about the Hessian (also with the real data). Also, there are no estimates - instead, the starting values are returned:
Warning message:
In model 'riclpm' Optimizer returned a non-zero status code 5. The Hessian at the solution does not appear to be convex. See ?mxCheckIdentification for possible diagnosis (Mx status RED).
> summary(res)
Summary of riclpm
The Hessian at the solution does not appear to be convex. See ?mxCheckIdentification for possible diagnosis (Mx status RED).
free parameters:
name matrix row col Estimate Std.Error A
1 x_x A cx2 cx1 0.1 NA !
2 y_x A cy2 cx1 0.1 NA !
3 x_y A cx2 cy1 0.1 NA !
4 y_y A cy2 cy1 0.1 NA !
5 riclpm.S[9,9] S RIx RIx 1.5 NA !
6 riclpm.S[9,10] S RIx RIy 0.1 NA !
7 riclpm.S[10,10] S RIy RIy 1.5 NA !
8 vx1 S cx1 cx1 0.1 NA !
9 vx S cx2 cx2 0.1 NA !
10 rxy1 S cx1 cy1 0.1 NA !
11 vy1 S cy1 cy1 0.1 NA !
12 rxy S cx2 cy2 0.1 NA !
13 vy S cy2 cy2 0.1 NA !
14 riclpm.M[1,11] M 1 cx1 0.1 8601467937 !
15 riclpm.M[1,12] M 1 cx2 0.1 8866184397 !
16 riclpm.M[1,13] M 1 cx3 0.1 9126759905 !
17 riclpm.M[1,14] M 1 cx4 0.1 7286763147 !
18 riclpm.M[1,15] M 1 cy1 0.1 8601467226 !
19 riclpm.M[1,16] M 1 cy2 0.1 8866192940 !
20 riclpm.M[1,17] M 1 cy3 0.1 9126760586 !
21 riclpm.M[1,18] M 1 cy4 0.1 7286752751 !
Log in or register to post comments
Interestingly, if I re-run
Log in or register to post comments
In reply to Interestingly, if I re-run by cjvanlissa
Starting values are not feasible
I'm not sure why there's no warning about the infeasible start when running the model with SLSQP, which is the on-load default optimizer. I think there ought to be such a warning. It's a useful diagnostic.
Log in or register to post comments
In reply to Starting values are not feasible by AdminRobK
Thank you, AdminRobK! I
Log in or register to post comments
In reply to Thank you, AdminRobK! I by cjvanlissa
start values
As far as finding good start values is concerned, mhunter has already in this thread mentioned `mxTryHard()` and `mxAutoStart()`.
Log in or register to post comments
Starting values matter
As a general rule, starting values of zero are not a good idea for many parameters in many models. The initial problem was that you started a covariance matrix at all zeros. OpenMx probably (depending on mxOptions) moved these starting values to all 0.1. However, a covariance matrix of all 0.1 is also nonsense. So, you gave OpenMx nonsense implausible starting values and OpenMx did not work.
When I changed the starting value of the variances of `RIx` and `RIy` to 1.5, OpenMx did not find a reasonable solution, but at least it was able to start. `mxTryHard()` tries several "random" starting values, and at lease one of those worked to get a reasonable solution.
OpenMx requires users to think about plausible starting values for their parameters. lavaan generally does not. One option, if you're really struggling to think of plausible starting values is to use `mxAutoStart()` which uses unweighted (or optionally weighted) least squares to find starting values on many models.
ss <- mxAutoStart(riclpm)
res <- mxRun(ss)
Log in or register to post comments
In reply to Starting values matter by mhunter
Ahh, of course. I somehow
Log in or register to post comments
Exact Hamaker2015 specs
The relevant lines in your code are:
mxPath(from=xminone, arrows=2, free=TRUE, values=c(.1), labels = "vx"),
mxPath(from=yminone, arrows=2, free=TRUE, values=c(.1), labels = "vy"),
Also the are no covars between xminone and yminone, it should be between vx and vy (or I am missing something). The line below would need to be edited too.
mxPath(from=xminone, to = yminone, arrows=2, free=TRUE, values=0, labels = "rxy"),
Anyway, if I make both changes so to be exactly the paper's spec I always end up with "All fit attempts resulted in errors - check starting values or model specification".
- Have you tried to reproduce Hamaker's exact specification?
Thanks
Log in or register to post comments