non-independent submodels
mStructure <- mxModel("Structure",
manifestVars = "Y", latentVars = "G",
mxPath(from = "G", to = "Y"),
## other model stuff)
mFull <- mxModel("Overall",
type = "RAM",
mxData(mydata[, c("all", "manifest", "variables", "for any submodel")], type = "raw"),
mMeasure,
mStructure)
My general hope being to work with one model, and once I have it in a form I want, use it in another model. I have tried several variants of the above putting data in the submodels and/or overall model without success. I am not looking for a worked example (though awesome if there is one lying around), just a "this can be done, keep looking" or "no *head smack* what were you thinking?". If I know its doable, once I get it worked out, I will post a working example for archive purposes.
There should be no problem
First, why are you using a multimodel structure? Using multiple models can be really great tool, but they add a great deal of complexity, as discussed in the next paragraph. Judging by your object names, it looks like you're trying to split a single model into measurement and structural components. The problem with this approach is that these two structures are, IMHO, never as separate as we would like, and always share the same data source. You seem to be trying to use mxModels to separate paths from one conceptual portion of your model from other portions. However, these parameters are all part of the same model, and the expected data covariance is not defined without all parts. You'd be better off updating a model, adding structural components to an existing measurement model. Feel free to give us more details and examples so we can help you build the best model you can.
Second, models to be analyzed need objective functions, and models analyzed as a non-independent set need interdependent objective functions. In the basic single model case, you provide some objective function either implicitly (type='RAM' builds an mxRAMObjective function for you) or explicitly. That is the function that is minimized, such that values of the free parameters are selected that make the minimum -2 log likelihood. If you have multiple models (for instance, a multiple group model), you'll have to specify objective functions for each group/model, and then an objective for the container model that holds them (usually an mxAlgebraObjective that minimizes an algebra like 'group1.objective + group2.objective'). This is part of why your model is failing; your separation of parameters across models yields one model with manifest-latent relationships, another model with latent-latent relationships, and a parent or container model with data and no relationships. When you specify multiple models, you have to specify how they interact with one another.
Hope this helps, and good luck with your models!
Log in or register to post comments
In reply to There should be no problem by Ryne
Thanks, that helps. I was
An example would be:
psrVars <- c("X1", "X2", "X3", "X4")
DV <- "CESD"
manifests <- c(psrVars, DV)
latents <- "PSR"
mD <- mxData(observed = mydat[, manifests], type = "raw")
mPSR <- mxPath(from = "PSR",
to = psrVars,
values = c(1, 1, 1, 1),
labels = paste("b", psrVars, sep = ''))
mFVar <- mxPath(from = latents, arrows = 2,
free = FALSE, values = 1, labels = paste("v", latents, sep = ''))
mFMean <- mxPath(from = "one", to = latents,
free = FALSE, values = 0, labels = paste("m", latents, sep = ''))
mMean <- mxPath(from = "one", to = psrVars,
labels = paste("m", psrVars, sep = ''))
mVar <- mxPath(from = psrVars, arrows = 2,
labels = paste("v", psrVars, sep = ''))
mSV <- mxPath(from = DV, arrows = 2, labels = paste("v", DV, sep = ''))
mSM <- mxPath(from = "one", to = DV, labels = paste("m", DV, sep = ''))
mTheory <- mxPath(from = "PSR", to = DV,
arrows = 1, free = TRUE, values = 1, labels = "bPSR")
mFull <- mxModel(model = "PSR and CESD",
type = "RAM",
manifestVars = manifests, latentVars = latents,
mD,
mPSR, mFVar, mFMean,
mMean, mVar,
mSV, mSM, mTheory)
If the outcome (DV) changes, or I want to look at mediation, mPSR, mFVar, mFMean, mMean, and mVar all stay the same. I was basically hoping to somehow bundle them into a single object so the model looked more like:
mFull <- mxModel(model = "PSR and CESD",
type = "RAM",
manifestVars = manifests, latentVars = latents,
mD,
mMeasure, # contains all paths related just to the measurement
mSV, mSM, mTheory)
This is a simple example, but in more complex measurement models, it seemed like it would be nice. Though perhaps creating many small mxPath objects is not an optimal workflow. Conceptually, I was thinking of something like this in R:
## I want these two vectors
c("a", "b", "c", "d", "e", "g") #1
c("a", "b", "c", "d", "e", "h") #2
# always want a to e so simplify the above to
x <- c("a", "b", "c", "d", "e")
c(x, "g") #1 <-- the lazy way
c(x, "h") #2
Log in or register to post comments
In reply to Thanks, that helps. I was by JWiley
I am having trouble
c("a", "b", "c", "d", "e", "g")
fits into the example that you gave. But in any case, you may be able to improve your workflow by writing a function that accepts some form of input, and returns a new model on output. As at outline, it would look something like:And then you would call the modelCreator with different values for the input.
Log in or register to post comments
In reply to I am having trouble by mspiegel
Thanks! That makes a lot of
The more I play with it, the less I am sure it really improves workflow as much as I envisioned, but in any case for archival purposes, a clean way to do it is easy using lists and do.call:
mydat <- data.frame(X1 = rnorm(400), X2 = rnorm(400), X3 = rnorm(400),
X4 = rnorm(400), CESD = runif(400))
psrVars <- c("X1", "X2", "X3", "X4")
DV <- "CESD"
manifests <- c(psrVars, DV)
latents <- "PSR"
mD <- mxData(observed = mydat[, manifests], type = "raw")
mMeasure <- list(
mxPath(from = "PSR", to = psrVars,
values = c(1, 1, 1, 1), labels = paste("b", psrVars, sep = '')),
mxPath(from = latents, arrows = 2,
free = FALSE, values = 1, labels = paste("v", latents, sep = '')),
mxPath(from = "one", to = latents,
free = FALSE, values = 0, labels = paste("m", latents, sep = '')),
mxPath(from = "one", to = psrVars, labels = paste("m", psrVars, sep = '')),
mxPath(from = psrVars, arrows = 2, labels = paste("v", psrVars, sep = '')))
mSV <- mxPath(from = DV, arrows = 2, labels = paste("v", DV, sep = ''))
mSM <- mxPath(from = "one", to = DV, labels = paste("m", DV, sep = ''))
mTheory <- mxPath(from = "PSR", to = DV,
arrows = 1, free = TRUE, values = 1, labels = "bPSR")
mFull <- do.call("mxModel", c(mMeasure, list(
model = "PSR and CESD", type = "RAM",
manifestVars = manifests, latentVars = latents, mD,
mSV, mSM, mTheory)))
Log in or register to post comments
In reply to Thanks! That makes a lot of by JWiley
This looks good, but I share
In addition to the two styles we've already showed, you can update MxModel objects using the mxModel function as shown below. It would allow you to build incrementally, but save you the step of psuedo-compiling at the end. Each line takes the model, adds a new path and returns the appended model to the mMeasure object.
mMeasure <- mxModel("Model Name")
mMeasure <- mxModel(mMeasure, mxPath("x", "y", ....))
mMeasure <- mxModel(mMeasure, mxPath("a", "b", ....))
Log in or register to post comments