You are here

multilevel path/structural equation models in OpenMx

18 posts / 0 new
Last post
Soyoung's picture
Offline
Joined: 05/08/2017 - 11:45
multilevel path/structural equation models in OpenMx
AttachmentSize
File Data1.26 MB
PDF icon Mplus code158.41 KB

Hi,

Is it possible to estimate multilevel path/structural equation models with OpenMx?
If it is possible, is there an example code for multilevel mediation (path) model?

Attached files are the example of multilevel path model using Mplus.
Source: Heck, R. H., & Thomas, S. L. (2015). An introduction to multilevel modeling techniques: MLM and SEM approaches using Mplus. Routledge.

Hope I can do the same analysis using OpenMx.

Thank you in advance.
Soyoung.

AdminHunter's picture
Offline
Joined: 03/01/2013 - 11:03
Yep

It is possible to estimate multilevel structural equations in OpenMx. This paper by Pritikin et al. discusses many of the details and provides some example scripts.

Many-Level Multilevel Structural Equation Modeling: An Efficient Evaluation Strategy

AdminJosh's picture
Offline
Joined: 12/12/2012 - 12:15
voila

Here's a similar model (see attachment). You probably need to add/remove a few paths to make it identical to what you posted. I find it tedious to read Mplus model diagrams or tables.

File attachments: 
Soyoung's picture
Offline
Joined: 05/08/2017 - 11:45
fabulous

Thank you all.

Two more questions.
Please check the attached file.

[1]
I revised the code, and i though I made the same model.
BUT I found these results are not identical in terms of estimates.
Why did these have different results?
Which Estimation method the OpenMx use?
Mplus uses Robust-ML.

[2]
I want to estimate indirect effects in Multilevel SEM.
How can I set a product term (indirect effect parameter) in OpenMx?

AdminJosh's picture
Offline
Joined: 12/12/2012 - 12:15
questions
  1. See imxRobustSE

  2. Create an mxAlgebra and use mxCI or mxSE to request confidence intervals on it. See attached code.

File attachments: 
Soyoung's picture
Offline
Joined: 05/08/2017 - 11:45
Thank you

Thank you so much for your kind response.
It was very helpful.

All the best,
Soyoung.

AdminNeale's picture
Offline
Joined: 03/01/2013 - 14:09
Agreement

Hi Soyoung

Could you confirm that you were able to get the same estimates and goodness-of-fit statistics with the multilevel model in OpenMx when compared to Mplus?

Thanks
Mike

Soyoung's picture
Offline
Joined: 05/08/2017 - 11:45
could not get the identical results

Hi, Mike.
I still could not get the identical results.
I am curious why these are different.

First, in terms of model fit statistics, two results were almost same.

  Mplus OpenMx
RMSEA 0 0
CFI 1 NA
TLI 1.001 1

BUT I don't think this example is suitable here, because these fit values are too perfect. It should be tested in the other data.

 

Second, in terms of estimates, I could not get the same estimates.
I'm trying to figure out why there are different results.

File attachments: 
AdminRobK's picture
Offline
Joined: 01/24/2014 - 12:15
imxRobustSE()

I am pretty sure that imxRobustSE() does not correctly handle multilevel data; the matter of whether or not it does is currently a matter of disagreement among the OpenMx development team. I suggest you not rely too much on the robust SEs you get out of OpenMx.

Soyoung, could you post the OpenMx script you're currently working from?

Soyoung's picture
Offline
Joined: 05/08/2017 - 11:45
sure

Hi Rob

Following code is based on what Dr.Pritikin provided.
You can find the data in post #1 .

library(OpenMx)
flatData <- read.table("ch4mv.dat")
colnames(flatData) <- c("orgid",'female','white',
                   'satpay','morale','org1','org2','benefit','cond',
                   'resour','zproduct','lev1wt','lev2wt')
 
level1 <- flatData[,c('benefit','cond','female','white','orgid')]
level2 <- flatData[!duplicated(flatData$orgid),c('orgid', 'org1','org2','zproduct')]
 
orgModel <- mxModel(
  "org", type="RAM",
  mxData(level2, 'raw', primaryKey = "orgid"),
  manifestVars = c('zproduct'),
  latentVars = c('Benefits','Conditions', 'org1','org2'),
  mxPath(c('zproduct','Benefits','Conditions'), arrows=2, values=1),
  mxPath('Benefits','Conditions', arrows=2),
  mxPath('one', 'org1', labels='data.org1', free=FALSE),
  mxPath('one', 'org2', labels='data.org2', free=FALSE),
  mxPath('org1', c('Benefits', 'Conditions')),
  mxPath('org2', 'zproduct', labels="a"),
  mxPath('one', 'zproduct'),
  mxPath('zproduct', c('Benefits','Conditions'), labels=paste0('b',1:2)),
  mxMatrix(nrow=2, ncol=1, free=TRUE, labels=paste0('b',1:2), name='B'),
  mxAlgebra(B * a, name="indirect")
)
 
empModel <- mxModel(
  "emp", type="RAM", orgModel,
  mxData(level1, 'raw'),
  manifestVars = c('benefit','cond'),
  latentVars = c('female','white'),
  mxPath('one','female', labels='data.female', free=FALSE),
  mxPath('one','white', labels='data.white', free=FALSE),
  mxPath(c('female','white'), c('benefit','cond'), connect = "all.bivariate"),
  mxPath(c('benefit','cond'), arrows=2, connect = "unique.pairs", values=c(1,0,1)),
  mxPath('org.Benefits', 'benefit', values=1, free=FALSE, joinKey = "orgid"),
  mxPath('org.Conditions', 'cond', values=1, free=FALSE, joinKey = "orgid"),
  mxPath('one', c('benefit','cond')),
  mxCI("org.indirect")
)
 
ch4M3 <- mxRun(empModel, intervals=TRUE)
summary(ch4M3)
imxRobustSE(ch4M3)
AdminRobK's picture
Offline
Joined: 01/24/2014 - 12:15
Under x86_64 Linux/GNU, I

Under x86_64 Linux/GNU, I substantively reproduce the OpenMx results you report with all 3 gradient-descent optimizers (script and output are attached).

Could you post the full output from MPlus? In particular, I'm curious if the -2logL matches.

Soyoung's picture
Offline
Joined: 05/08/2017 - 11:45
full output

Yes. Attachment is full output.

Mplus reports LL -40521.828.
(-2) * (-40521.828) = 81043.656

Thank you.
Soyoung.

File attachments: 
AdminNeale's picture
Offline
Joined: 03/01/2013 - 14:09
ML vs MLR?

Hi Soyoung, I notice that the estimator in MPlus is MLR, whereas in OpenMx it is FIML. Could you try it with ML (FIML) in Mplus to see if that changes the results?

Cheers
Mike

Soyoung's picture
Offline
Joined: 05/08/2017 - 11:45
different

Hi Mike.
Attachment is the result of FIML,
but this is almost same as the result of MLR of Mplus,
and the estimates does not match the result of OpenMx.

I wonder why the two results are different...Where does the difference come from?
Is there a way to check local-maxima in OpenMx, by any chance?

Thank you.
Soyoung.

File attachments: 
jpritikin's picture
Offline
Joined: 05/24/2012 - 00:35
fit value

One way to debug this is to load the parameter vectors into the OpenMx model using omxSetParameters and then evaluate the fit at that point using mxRun(mxModel(model, mxComputeOnce('fitfunction','fit'))). If the Mplus fit matches at a specific parameter vector then the models are likely the same. If the fit doesn't match then the models are different.

AdminRobK's picture
Offline
Joined: 01/24/2014 - 12:15
already tried it
One way to debug this is to load the parameter vectors into the OpenMx model using omxSetParameters and then evaluate the fit at that point using mxRun(mxModel(model, mxComputeOnce('fitfunction','fit'))).

I already tried that (see my post, presently #17, below). The fit values don't match.

jpritikin's picture
Offline
Joined: 05/24/2012 - 00:35
robust

Good point Rob. I am not sure what Robust-ML means for multilevel models.

AdminRobK's picture
Offline
Joined: 01/24/2014 - 12:15
It appears that imxRobustSE()

It appears that imxRobustSE() does not calculate robust SEs in a manner theoretically correct for multilevel data (e.g., Freedman 2006).

It also appears that what OpenMx and MPlus are doing in this case are different enough that their results shouldn't be compared to each other. See the attached script and output. When OpenMx calculates the fit at MPlus' solution, OpenMx returns a different fit from MPlus. Further, I can start OpenMx at MPlus' solution, and OpenMx still returns the same solution it has before (with a fit value of 82001.55).

I don't know OpenMx's multilevel feature very well, and I don't know MPlus at all, so I'm not sure what might explain the difference (or even if Soyoung's syntax is even fitting equivalent models in the two software packages). Perhaps a difference in how the two programs internally handle zero-variance exogenous regressors? Does MPlus drop normalizing constants from its loglikelihood?

Log in or register to post comments