I have fit two saturated models and have created correlation matrices from the expected covariance matrices using the cov2cor function. I would like to constrain the correlation matrices to equality between these models without constraining the covariance matrices.
I have tried adding a mxConstraint object to the combined model but I get errors and I am not able to constrain them by equating labels, as far as I can figure out. I'm just wondering if anyone has done anything like this? I'm sure I'm missing something very simple - I am brand new to all of this so the learning curve is a little steep at the moment.
Thanks!
Gretchen
Try parameterizing the covariance matrices in terms of correlations and standard deviations. Your two models would have the same correlation matrix, but different SDs. The labels for the correlations would be the same for both models, but the labels for the SDs would be different.
For example, suppose
R
is the correlation matrix, andD
is a diagonal matrix that has the model's SDs on its diagonal. Then, the MxAlgebraD %*% R %*% D
would give you the model's covariance matrix. Alternately, supposeR
is the correlation matrix as before, ands
is a column vector containing the model's SDs. Then, the MxAlgebraR * (s%*%t(s))
would also give you the model's covariance matrix.Obviously, this approach doesn't produce a covariance matrix from the product of Cholesky factors, so the resulting covariance matrix could become non-positive-definite during optimization. It's therefore especially important to pick good start values.
Does this help? I could be more specific if you posted some of your script.
Hey Rob! I hear a lot about you from Matt and Bridget. Thank you so much for your help!
I think I understand and have incorporated what you said. I am pretty sure I am now having trouble with the start values as you predicted. Do you have any words of wisdom about these?
I have attached my script in the hopes that it helps.
Thanks!
Gretchen
The correlation matrix (since I'm not sure you need two) should be of type
"Stand"
(i.e., standardized), not"Symm"
(i.e., merely symmetric). As it is now, your script is allowing the diagonal elements of the correlation matrices to be free parameters, but they must be fixed at 1.First, define
cor_label
differently:Now, define the correlation matrix as:
Like I said, I think you probably only need one correlation matrix, which you can just use in both the males' and females' models. You want to set up a model in which the correlations are the same for males and females, right?
When you set up the supermodel that will contain the models for the males and females, define it like this:
If you take a look at the start values for the correlations, with
R$values
, you'll see that they're all zero. You might want to change them to something more reasonable--something closer to what you think their estimate will be. You could do that by providing start values via thevalues
argument tomxMatrix()
when you createR
, or by altering the 'values' matrix directly (e.g.,R$values[1,2] <- 0.5
) before you putR
into a model, or by usingomxSetParameters()
oneqCor_gender
once it's been created.Thank you. I do only need one correlation matrix because I want to be the same - not sure why I thought two were necessary at all. And I see how you set the diagonals of R to be fixed - I didn't realize how that was done, so that is immensely helpful.
Hopefully this is my last question, but when I try to run the combined model with the mxFitFunctionMultigroup added in, I get this error:
Running eqCor_gender
Error: eqCor_gender.fitfunction: cannot locate algebra/fitfunction 'males.fitfunction'
I feel like I have tried everything to figure out what this means/what is missing. Do you have any ideas what I might be doing wrong?
I've attached my updated script again. Thank you again for your help!
Ah, OK, I think we're both getting tripped up on the order of arguments supplied to
mxModel()
. Try this instead:The first argument to
mxModel()
ismodel
, which can either be a character string or an MxModel object. If it's a string, the function creates a new MxModel object with name equal to the string. If it's an MxModel object, the function pulls all of that object's contents into the MxModel object it returns. So, what I think was happening with your syntax was thatmxModel()
was returning a model that contained all of the contents ofmodel_m
, plusmodel_f
itself as a submodel. Note that it did not containmodel_m
as a submodel, so there was nothing called "males.fitfunction" in its namespace.So basically, don't provide an MxModel object as argument
model
unless you want to get that same MxModel back, with additional stuff possibly added to it.I think the mxFitFunctionMultigroup() just wants a list of model names, so
There was a bug recently fixed in trunk. If you are using 2.0.1 then you should use "model.fitfunction" to avoid problems.
Ah, totally understand now. I hadn't considered the order of the arguments that I had put in.
Thank you again for all of your help! Very much appreciated!