Specifying the Correlation Among all Exogenous Variables

9 replies [Last post]
kkelley's picture
Offline
Joined: 08/04/2009

Hello,

I was wondering if there is an easy way to tell OpenMx to estimate all of the correlations among a set of exogenous variables, rather than specifying each of the correlations line-by-line in mxPath statements.

For example, suppose exogenous variables are:
IVs <- c("COREREL", "JOBPAY", "SEX_2")

I tried to automate a way to include the exogenous correlations for an arbitrary number of variables as:

These.Pairs <- combn(IVs, 2)
Here <- NA
for(i in 1:dim(These.Pairs)[2])
{
Here <- rbind(Here, paste("mxPath(from=", These.Pairs[1,i], ", to=", These.Pairs[2,i], ", arrows=2, free=TRUE),", sep=""))
}
Here <- na.omit(rbind(Here))

which produces:
> Here
[,1]
"mxPath(from=COREREL, to=JOBPAY, arrows=2, free=TRUE),"
"mxPath(from=COREREL, to=SEX_2, arrows=2, free=TRUE),"
"mxPath(from=JOBPAY, to=SEX_2, arrows=2, free=TRUE),"
attr(,"na.action")
Here
1
attr(,"class")
[1] "omit"

The structure of the mxPath statements is correct, but I've not been able to appropriately "feed" OpenMx the information contained in "Here." I'm guessing there is an easier way to do this or a way to get OpenMx to understand the "Here" object. Any thoughts would be appreciated.

Thanks,
Ken

kkelley's picture
Offline
Joined: 08/04/2009
Thanks

Thanks for the very quick replies. I thought there might be a simple solution - and there was!

Ken

kkelley's picture
Offline
Joined: 08/04/2009
Still Getting Errors

Ok, after I tried to implement some of this, I'm running into problems. So, from the comments all=TRUE with 2 headed arrows will not work, so I'm (obviously) not going that route. First, I try just a basic way to obtain what is just a multiple regression model.

Here is some example code with artificial data. I'll mention that I'm trying to automate the OpenMx syntax from what is defined above the line of #s.

N<- 500
Data.of.Interest <- as.data.frame(matrix(rnorm(N*4), N, 4))
colnames(Data.of.Interest) <- c("JOBSATA", "COREREL", "JOBPAY", "hrs1")

# Model specifications.
DV <- "JOBSATA"
IVs <- c("COREREL", "JOBPAY", "hrs1")
Variance.Labels <- paste("Var_", c(DV, IVs), sep="")
Path.Labels <- paste("Coef_", IVs, sep="")
Path.Means <- c("Intercept", paste("Mean_", IVs, sep=""))

# This shows the specification for a regression model given the above noted specifications.
###############################################################################################################################################################################

MxModel <- mxModel("Regression Path Specification Test",
type="RAM",
mxData(observed=Data.of.Interest, type="raw"),
manifestVars=c(DV, IVs),
mxPath(from=c(DV, IVs), arrows=2, free=TRUE, labels=Variance.Labels), # Variances. 4 estimates.
mxPath(from=IVs, to=DV, arrows=1, free=TRUE, labels=Path.Labels), # Path coefficients. 3 estimates.
mxPath(from=IVs[1], to=IVs[2], arrows=2, free=TRUE, labels="Cov12"), # Covariance of two exogenous variables. 1 estimate.
mxPath(from=IVs[1], to=IVs[3], arrows=2, free=TRUE, labels="Cov13"), # Covariance of two exogenous variables. 1 estimate.
mxPath(from=IVs[2], to=IVs[3], arrows=2, free=TRUE, labels="Cov23"), # Covariance of two exogenous variables. 1 estimate.
mxPath(from="one", to=c(DV, IVs), arrows=1, free=TRUE, labels=c(Path.Means)) # Means (first one is the intercept of the regression model).
)

MxOutput <- mxRun(MxModel)

When I run the above I get:

Running Regression Path Specification Test
Error: The job for model 'Regression Path Specification Test' exited abnormally with the error message: Expected covariance matrix is not positive-definite in data row 408 at iteration 0.

However, this is (if I have specified everything properly) just a 3 predictor multiple regression model with 10 covariance estimates being requested from data that has 4*5/10 10 pieces of information. So, it should be a saturated model and as far as I can tell this should work fine. Am I missing something simple? When I remove the three mxPath statements for the covariances of the exogenous variables, I get results (but not what I want, since removing those paths implies a covariance of 0 among the three exogenous variables.

Additionally, when I replace the three mxPath covariance statements with [ first defining: Exog.Covs <- combn(IVs, 2) ] the following:
mxPath(Exog.Covs[1,], Exog.Covs[2,], arrows=2, free=TRUE)
I get the same error as above.

Any (further) help on this issue would be appreciated.
Thanks,
Ken

Ryne's picture
Offline
Joined: 07/31/2009
There are no starting values

There are no starting values in your code, so all parameters begin at zero. This means your expected covariance matrix is zero, and thus non-positive definite. Give all of your variables non-zero variances and its should work.

I added the 'all=TRUE' stuff too, if you want to see how it works. The labels are a little fancier than they need to be. 'all=TRUE' works; it's just that you'll need to (a) either set excludeself=TRUE so that you can give variances and covariances different starting values or make a second mxPath statement for the variances, as you have, and put it after the covariances 'all=TRUE' statement, and (b) know that all=TRUE specifies both "A with B" and "B with A", so it'll make twice as many covariances as you need. That's not a problem, as "B with A" just overwrites "A with B", but it makes labeling hard.

N<- 500
Data.of.Interest <- as.data.frame(matrix(rnorm(N*4), N, 4))
colnames(Data.of.Interest) <- c("JOBSATA", "COREREL", "JOBPAY", "hrs1")
 
# Model specifications.
DV <- "JOBSATA"
IVs <- c("COREREL", "JOBPAY", "hrs1")
Variance.Labels <- paste("Var_", c(DV, IVs), sep="")
Path.Labels <- paste("Coef_", IVs, sep="")
Path.Means <- c("Intercept", paste("Mean_", IVs, sep=""))
Cov.Labels <- paste("Cov", rep(IVs, each=3), IVs, sep="_")
# This shows the specification for a regression model given the above noted specifications.
###############################################################################################################################################################################
 
MxModel <- mxModel("Regression Path Specification Test",
type="RAM",
mxData(observed=Data.of.Interest, type="raw"),
manifestVars=c(DV, IVs),
mxPath(from=c(DV, IVs), arrows=2, free=TRUE, values=1, labels=Variance.Labels), # Variances. 4 estimates.
mxPath(from=IVs, to=DV, arrows=1, free=TRUE, values=1, labels=Path.Labels), # Path coefficients. 3 estimates.
mxPath(from=IVs, arrows=2, all=TRUE, free=TRUE, values=0.5, labels=Cov.Labels, excludeself=TRUE), # Covariances of exogenous variables. 3 estimates.
mxPath(from="one", to=c(DV, IVs), arrows=1, free=TRUE, labels=c(Path.Means)) # Means (first one is the intercept of the regression model).
)
 
test <- mxRun(MxModel)
 
summary(test)

mspiegel's picture
Offline
Joined: 07/31/2009
Yes, arrows=2 and all=TRUE

Yes, arrows=2 and all=TRUE works when the labels are all different values, and the model specification doesn't care whether a path is labelled "Cov_X_Y" or "Cov_Y_X". It gets trickier when we want to equate some of these paths to each other.

mspiegel's picture
Offline
Joined: 07/31/2009
How about: pairs <-

How about:

   pairs <- combn(IVs, 2)
   paths <- mxPath(pairs[1,], pairs[2,], arrows=2, free=TRUE)

Ryne's picture
Offline
Joined: 07/31/2009
I think Tim Bates beat my to

I think Tim Bates beat my to this. The 'all' argument specifies that everything in the 'from' argument be paired with the 'to' argument. Use 'exclude self' to prevent the variances from being added (else you have to mess with starting values to make sure that the correlations between parameters aren't perfect). This will specify both the "a with b" and "b with a" paths, so keep that in mind when generating labels.

mxPath(from=myVar, to=myVar, all=TRUE, 
   arrows=2, free=TRUE, values=.5, excludeself=TRUE)

mspiegel's picture
Offline
Joined: 07/31/2009
No, don't use the all=TRUE

No, don't use the all=TRUE flag when specifying double-headed arrows. We never successfully resolved the following issue: http://openmx.psyc.virginia.edu/thread/850.

tbates's picture
Online
Joined: 07/31/2009
resolving double headed arrows with all=T

Hi Mike,
What needs to be done? I guess something like

if reverseMe(thisPath) in pathsMade {
	# do nothing
}else{
	pathsMade[n]=thisPath
	n=n+1; 
}

nasty bug elsewise

tbates's picture
Online
Joined: 07/31/2009
all=T

I think all you need is to run mxPath with the "all" parameter set to true (excludeself=T if you don't want variance of each thing with itself. You don't even need the "to" as it is assumed if missing.

mxPath(from=c("a","b"),arrows=2, all=T)
mxPath 
@from:  'a', 'a', 'b', and 'b' 
@to:  'a' and 'b' 
@arrows:  2 
@values:  0 
@free:  TRUE 
@labels:  NA 
@lbound:  NA 
@ubound:  NA 
@excludeself:  FALSE 
<code/>