One standardized value does not match Mplus/lavaan

Posted on
Picture of user. 0avasns Joined: 12/09/2010
Hello fellow OpenMx-ers
In the interest of helping people transition to R, I have been converting the contents of an SEM seminar taught at our university from Mplus to OpenMx, also using lavaan for comparison. So I have a slightly complex path model with two exogenous variables, two mediating endogenous variables, and one outcome variable. The model produces the same fit indices and solutions (including estimates and SEs) in all three packages, and all but one standardized parameters are also identical. In particular, the modeled covariance between the residuals of the two endogenous (mediating) variables does NOT match, and I wonder if this is a bug somewhere or whether a different formula is used. Note that lavaan fully matches Mplus, it is only the standardized estimate in OpenMx that differs. In the demo data set used in the seminar the discrepancy is quite substantial (.68 vs. .30). I do not really know what this parameter should be divided by to be standardized, so I cannot check further myself. Code attached, using a dataset provided with lavaan, for easy checking; the problem is the same.
Replied on Mon, 04/01/2019 - 09:50
Picture of user. AdminRobK Joined: 01/24/2014

I reproduce the apparent discrepancy. Thank you for reporting it.

I'm running:

OpenMx version: 2.12.2 [GIT v2.12.2]
R version: R version 3.5.2 (2018-12-20)
Platform: x86_64-w64-mingw32
Default optimizer: CSOLNP
NPSOL-enabled?: Yes
OpenMP-enabled?: No

Replied on Mon, 04/01/2019 - 15:11
Picture of user. AdminRobK Joined: 01/24/2014

lavaan's default for `standardizedsolution()` uses a slightly different definition of what the "standardized" solution ought to be, compared to OpenMx. I can resolve the mismatch by passing argument `cov.std=FALSE` to `standardizedsolution()`.
Replied on Mon, 04/01/2019 - 16:18
Picture of user. tbates Joined: 07/31/2009

Great that you're helping people move to R! And great that Rob K got to the bottom of this in an hour or 2 and identified the choice in mplus/lavaan to use cov.std= TRUE.

Parenthetically, I made coded up the model using umxRAM as well, if you're assembling a transition guide.


# umx
library(umx); library(lavaan);
mVars <- c("x1","x2","t1","t2","t3")
uniRegMod = umxRAM("Demo", data = Demo.growth,
umxPath(v.m. = mVars),
umxPath(fromEach = c("x1","x2"), to = c("t1", "t2", "t3")),
umxPath(c("t1","t2"), to = "t3"),
umxPath("x1", with = "x2"),
umxPath("t1", with = "t2")
)
parameters(uniRegMod, patt = "t1_with_t2")
umxSummary(uniRegMod, show = "std")

Replied on Tue, 04/02/2019 - 03:21
Picture of user. 0avasns Joined: 12/09/2010

Thank you both very much for resolving the discrepancy and for pointing me to umx!
I was wondering if a reverse treatment might be available, causing OpenMx to produce a standardized solution matching Mplus (rather than causing lavaan to match OpenMx). From a purely practical standpoint, this would be very useful because people here are used to Mplus (many years of experience, and a lot of complex models and high-profile publications), and may be unlikely to be positive toward a switch to something that produces different results.
Thanassi
Replied on Tue, 04/02/2019 - 08:20
Picture of user. jpritikin Joined: 05/23/2012

You may also enjoy https://cran.r-project.org/web/packages/EasyMx/
Replied on Tue, 04/02/2019 - 10:36
Picture of user. tbates Joined: 07/31/2009

Hi @Thanassi,
Why not comment on [issue #159 at our github](https://github.com/OpenMx/OpenMx/issues/159). That would also give people a place to add references for any benefits either way. A path from Mplus to OpenMx should be smooth, but this might not be a road block in practice?