# Welcome to the OpenMx SEM modeling forum.

10 posts / 0 new
Offline
Joined: 07/30/2009 - 14:03
Welcome to the OpenMx SEM modeling forum.

This forum is designed for discussions about how to create and fit SEM models with OpenMx. This forum is designed to be about the nuts and bolts of how to use OpenMx rather than a general purpose SEM modeling forum. For questions about the models themselves, rather than how to implement them in OpenMx, please see the OpenSEM forums where models are split by many different types.

Offline
Joined: 08/23/2009 - 21:06
Hi All, I am wondering if it

Hi All,
I am wondering if it is possible to place constraints on lambda loadings (i.e., constraining the loadings of a two indicator construct to be equal, or constraining the average of a construct's loadings to equal 1 to set the scale by the effects coding method). I've been working primarily with the path specification approach, and I can't see an obvious way that this could be implemented, nor can I find any mention or suggestions in the documentation. Would this be something more easily achieved under the matrix specification approach? Any insight would be greatly appreciated.

Offline
Joined: 07/30/2009 - 14:03
Constraining free parameters

Constraining free parameters to be equal to one another is easy: just set their labels to be the same. For instance, starting with the script on the front page of the website, we could constrain two of the loadings to be the same by giving them both the label "lambda1".

require(OpenMx)
data(demoOneFactor)
manifests <- names(demoOneFactor)
latents <- c("G")
factorModel <- mxModel("One Factor", type="RAM",
manifestVars = manifests,
latentVars = latents,
mxPath(from=latents, to=manifests, labels=c("L1", "L1", "L3", "L4", "L5")),
mxPath(from=manifests, arrows=2),
mxPath(from=latents, arrows=2,
free=F, values=1.0),
mxData(cov(demoOneFactor), type="cov",
numObs=500))
summary(mxRun(factorModel))


Note that the vector of labels needs have the same number of elements as the number of paths (or be a single element in order to constrain all paths to be equal to one another).

One can create the kind of sum constraints you want by using the mxConstraint() function. This is a little more involved since you need to create an algebraic expression using mxAlgebra and a 1x1 constant matrix to hold your constant.

I won't write that example in this Forum just yet because we expect the syntax for this to be drastically simplified within the next week or so. Right now you would need to construct a matrix for each parameter, add all of those parameters together in an algebra, and then construct another 1x1 matrix with the number 5 in it and then use mxConstraint to enforce the equality constraint between the number 5 and the sum of the loadings.

Offline
Joined: 08/23/2009 - 21:06
Esteemed developers - Forgive

Esteemed developers -

Forgive the novice question. In the course of trying to learn OpenMx I have been adapting working code to fit new models and new data. Below is a model for what ought to be a simple saturated path model with 5 variables:

helpful -> politics, people, perform, jobsat
politics -> jobsat
people -> jobsat
perform -> jobsat

...with covarying residuals for politics, people, and perform, and therefore 20 parameters (7 paths, 5 variances, 3 covariances, 1 mean, 4 intercepts). I tried specifying a LISREL-type model with each MV serving as a perfect indicator of its corresponding LV (Fhelpful, etc.) and regressing the LVs on each other. OpenMx returns a "non-positive definite" error. I think I am specifying the model incorrectly, but cannot figure out how.

The error codes:

  $status$status[[1]]
[1] -1

$status[[2]] [1] -1$status[[3]]
[CHARSXP: "Covariance matrix is not positive-definite."]

Output also claims only 13 parameters are estimated rather than 20.

Many thanks,
Kris

require(OpenMx)
manifests <- names(multmedData)
latents <- c("Fhelp","Fpol","Fpeo","Fper","Fjob")
multmedModel <- mxModel("Multiple Mediator Model",
type="RAM",
mxData(multmedData, type="raw"),
manifestVars = manifests,
latentVars = latents,

# residual variances
arrows=2,
free=c(FALSE,FALSE,FALSE,FALSE,FALSE),
values=c(0,0,0,0,0),
labels=as.character(c(NA,NA,NA,NA,NA))
),

# latent variances and covariances
mxPath(from=c("Fhelp","Fpol","Fpeo","Fper","Fjob"),
arrows=2,
free=c(TRUE,FALSE,FALSE,FALSE,FALSE,
FALSE,TRUE,TRUE,TRUE,FALSE,
FALSE,TRUE,TRUE,TRUE,FALSE,
FALSE,TRUE,TRUE,TRUE,FALSE,
FALSE,FALSE,FALSE,FALSE,TRUE),
values=c(1,0,0,0,0,
0,1,1,1,0,
0,1,1,1,0,
0,1,1,1,0,
0,0,0,0,1),
labels=as.character(c("var11",NA,NA,NA,NA,
NA,"var22","cov32","cov42",NA,
NA,"cov32","var33","cov43",NA,
NA,"cov42","cov43","var44",NA,
NA,NA,NA,NA,"var55"))
),

mxPath(from=c("Fhelp","Fpol","Fpeo","Fper","Fjob"),
arrows=1,
free=c(FALSE,FALSE,FALSE,FALSE,FALSE),
values=c(1,1,1,1,1),
labels=as.character(c(NA,NA,NA,NA,NA))
),

# structural path coefficients
mxPath(from=c("Fhelp","Fhelp","Fhelp","Fhelp","Fpol","Fpeo","Fper"),
to=c("Fpol","Fpeo","Fper","Fjob","Fjob","Fjob","Fjob"),
arrows=1,
free=c(TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE),
values=c(1,1,1,1,1,1,1),
labels=as.character(c("a1","a2","a3","cp","b1","b2","b3"))
),

# means and intercepts
mxPath(from="one",
arrows=1,
free=c(FALSE,FALSE,FALSE,FALSE,FALSE,TRUE,TRUE,TRUE,TRUE,TRUE),
values=c(0,0,0,0,0,1,1,1,1,1),
labels=c("nu1","nu2","nu3","nu4","nu5","mean1","mean2","mean3","mean4","mean5")
)
)
multmedFit <- mxRun(multmedModel)
multmedFit@output
summary(multmedFit)

Any suggestions?

Many thanks,
Kris

Offline
Joined: 07/31/2009 - 15:24
It looks like when specifying

It looks like when specifying the paths under the line "# latent variances and covariances", you are expecting to specify 25 paths. Use the parameter all = TRUE to specify 5 x 5 paths. The default value for the 'all' parameter is FALSE, which makes 5 paths given 5 entries in the 'from' argument. Only if 'all' equals TRUE, then all sources are connected to all sinks.

Offline
Joined: 08/23/2009 - 21:06
Thanks! This gets me the

Thanks! This gets me the proper number of parameters, but still bad output:

  $status$status[[1]]
[1] -1

$status[[2]] [1] -1$status[[3]]
[CHARSXP: "Covariance matrix is not positive-definite."]

and now:

  Error in solve.default(model@output$hessian) : Lapack routine dgesv: system is exactly singular or:  Error in solve.default(model@output$hessian) :
system is computationally singular: reciprocal condition number = 0

the only other modification I made to the code above was to add "labels=as.character()" to the final mxPath statement, but that isn't the source of this problem.

Offline
Joined: 07/31/2009 - 14:25
might help to debug this by

might help to debug this by laying out the code into smaller chunks
just dashed this off, but i think it reflects the tasks you want

require(OpenMx)
manifests   = names(multmedData)
latents     = c("Fhelp","Fpol","Fpeo","Fper","Fjob")

multmedModel <- mxModel("Multiple Mediator Model", type="RAM",
mxData(multmedData, type="raw"),
manifestVars =manifests,
latentVars = latents,

# Residual variances
# Fix variance of measured vars to 0
# Latent variances
mxPath(from=latents, arrows=2, free=TRUE, values=1),
# Latent covariances
mxPath(from=latents, arrows=2, free=TRUE, values=1, All=TRUE),

# Structural path coefficients
# helpful -> politics, people, perform, jobsat
mxPath(from="Fhelp", to=c("Fpol","Fpeo","Fper","Fjob"), arrows=1, free=TRUE, values=1, labels=as.character(c("a1","a2","a3","cp")), # means and intercepts
# politics -> jobsat; people -> jobsat; perform -> jobsat
mxPath(from=c("Fpol","Fpeo","Fper"), to=c("Fjob","Fjob","Fjob"), arrows=1, free=TRUE, values=1, labels=as.character(c("b1","b2","b3")), # means and intercepts

# Set means
mxPath(from="one", to=c("Fhelp","Fpol","Fpeo","Fper","Fjob"),             arrows=1, free=TRUE, values=1, labels=c("mean1","mean2","mean3","mean4","mean5") )
)
multmedFit <- mxRun(multmedModel) multmedFit@output summary(multmedFit)

Offline
Joined: 08/23/2009 - 21:06
Thanks Tim. I made the code

Thanks Tim. I made the code as bare-bones as possible, ran it, and still I do not receive the expected output. Does it matter that the model is just-identified?

require(OpenMx)
manifests = names(multmedData)
latents = c("Fhelp","Fpol","Fpeo","Fper","Fjob")
multmedModel <- mxModel("Multiple Mediator Model", type="RAM",
mxData(multmedData, type="raw"),
manifestVars = manifests,
latentVars = latents,
mxPath(from=c("Fhelp","Fpol","Fpeo","Fper","Fjob"), arrows=2, free=TRUE, values=1),
mxPath(from=c("Fpol","Fpol","Fpeo"), to=c("Fpeo","Fper","Fper"), arrows=2, free=TRUE, values=1),
mxPath(from="Fhelp", to=c("Fpol","Fpeo","Fper","Fjob"), arrows=1, free=TRUE, values=1, labels=as.character(c("a1","a2","a3","cp"))),
mxPath(from=c("Fpol","Fpeo","Fper"), to=c("Fjob","Fjob","Fjob"), arrows=1, free=TRUE, values=1, labels=as.character(c("b1","b2","b3"))),
mxPath(from="one", to=c("helpful","politics","people","perform","jobsat"), arrows=1, free=FALSE, values=0, labels=as.character(c("nu1","nu2","nu3","nu4","nu5"))),
mxPath(from="one", to=c("Fhelp","Fpol","Fpeo","Fper","Fjob"), arrows=1, free=TRUE, values=1, labels=as.character(c("mean1","mean2","mean3","mean4","mean5"))))

multmedFit <- mxRun(multmedModel)
multmedFit@output
summary(multmedFit)

(sorry, my code runneth over)

Kris

Offline
Joined: 07/31/2009 - 15:12