Hi Tim and Mike,

This is the first time I am playing with real data, and since I understand lavaans syntax better than openMx's I decided to start with umx.

I am trying to specify a CP model with two latents, but my measured indicators represents parenting style and personality (big5), 10 variables in total. See fig 1. I think they are better conceptualized as two latents that can correlate, but only loads in part of the variables, the five personality traits and the five parenting styles.

Initially I thought that I could either use umx_make_Twins or remove the unwanted paths with umxModify( update = ). However, it seems that with umxModify I can only remove the paths, but I cant add the correlation between latents. I ended up with fig 2.

- What should be the best approach to allow the two latents in fig 2 to correlate?

Below is a minimal working example to facilitate discussion:

dt <- ZA6701_en_add_scales_wid1_v4.0.0 %>% left_join(ZA6701_en_master_v4.0.0, by = "pid") %>% transmute(zygosity = zyg0102, parcontt1 = as.numeric(parcontt), parcontt2 = as.numeric(parcontt), parincot1 = as.numeric(parincot), parincot2 = as.numeric(parincot), parmonit1 = as.numeric(parmonit), parmonit2 = as.numeric(parmonit), parnegct1 = as.numeric(parnegct), parnegct2 = as.numeric(parnegct), parwarmt1 = as.numeric(parwarmt), parwarmt2 = as.numeric(parwarmt), peragre1 = as.numeric(peragre), peragre2 = as.numeric(peragre), percons1 = as.numeric(percons), percons2 = as.numeric(percons), perneur1 = as.numeric(perneur), perneur2 = as.numeric(perneur), perextr1 = as.numeric(perextr), perextr2 = as.numeric(perextr), peropen1 = as.numeric(peropen), peropen2 = as.numeric(peropen)) selDVs <- c("parcontt","parincot", "parmonit", "parnegct", "parwarmt", "peragre", "percons", "perneur", "perextr","peropen") vupdate <- c("cp_loadings_r6c1", "cp_loadings_r7c1", "cp_loadings_r8c1", "cp_loadings_r9c1", "cp_loadings_r10c1", "cp_loadings_r1c2", "cp_loadings_r2c2", "cp_loadings_r3c2", "cp_loadings_r4c2", "cp_loadings_r5c2") m2 <- umxCP(data = dt, mzData = "1: monozygotic", dzData = "2: dizygotic", selDVs = selDVs, sep = "", nFac = 2) umx m3 <- umxModify(m2, update = vupdate, comparison = F) plot(m3) parameters(m2) <blockcode> Thanks, Luis

Hi Luis

I can't test because tidyverse doesn't exist for my version of R (4.0.3 which has been out ~2 months). But I can tell you how to do it. umxCP sets up OpenMx models with matrices. Most of these are in the 'top' model within the model that umxCP returns.

For example, the a paths are estimated in matrix a_cp, which we can see an example of by running the example from the ?umxCP help documentation.

If you wish to allow the factors to correlate, you could use the Cholesky approach, which simply means freeing up the elements in the lower triangle of the a_cp, c_cp and e_cp matrices. If you only have 2 factors, this is easy because there's only one element in the lower triangle, so you could do something like this as Step 1:

Step 2 is to change the factor loading matrix, which is (cryptically) in matrix cp_loadings:

You can fix values to zero with a umx function, or with base OpenMx it might be done with omxSetParameters():

There are various tricks for using wildcards for labels that umx has that could be handy way to find all the factor loadings in a column without having to list them all out.

Step 3 is to run the model again once it has been modified.

Thanks Mike,

Seems easy enough, however I am stuck in Step 1, as umx models seems not to allow direct modifications. So with:

I get:

I tried mxModel() with something like:

But this is the wrong syntax.

best

First, there should be no general difference between models auto-generated by umx and those specified manually by users. Both are OpenMx models.

Second, sometimes direct tweaking of matrices isn't allowed (and I'm not sure what conditions affect this). Possibly, omitting the $submodels bit would solve the issue.

You can always replace the entire matrix by extracting it to an object first, modify that object, then put the matrix back into the model again. Sometimes it may be necessary to use mxModel(), with syntax of the form:

where matrixToBeReplaced has the same name as the one it is replacing.

HTH

This error occurs when exactly? Because, at first, you're not touching OpenMx, just basically modifying a matrix with base r. I remember setting up an identical model with umxcp. However, I just let the factors correlate (correlated factors) instead of specifying Cholesky.

Thanks Leo,

This happens if I just try to change the content of the R object within the model like:

The same error happens. I am not sure if umx models are in any way different from the openMx ones. But I checked the structure and the above line was supposed to work. You mentioned a model with correlated factors, and I found an undocumented option in umx "correlatedA = T" that does what I wanted in terms of correlation (I think); the rest of Mike's instructions gets me where I wanted with this model.

Many thanks.

A 2 common pathway CP model with CP 1 loading one set of variables and CP 2loading the second set makes sense. The short answer to the question about why you can't manually add correlations after a model is built, is that the default umxCP uses a diag matrix which can't implement the off diagonal covariances you want. SO you need to say correlatedA=TRUE when creating the model. This should have been called something else but... history.

The install_github(tbates/umx") version now deprecates

`correlatedA`

in favour of`correlatedACE`

which is more accurately named, and defaults to leaving the lower triangle fixed at zero, allowing you to free up the (few) paths you want.To create a 2-factor CP model, just set

`nFac=2`

To restrict what manifests each CP loads on, in the resultant model, delete the paths from CP1 to the set 2 manifests, and from CP2 to the set 1 manifests using labels.

Paths from cp1 are in column 1 of the

`cp_loadings`

matrix. and labeled as "cp_loadings_r1c1"You can match the relevant pattern with regular expressions, or if you like more concrete or fool proof approach, make a list and drop that... e.g.:

you would then need to free the covariance of the a paths if you think that makes sense.

Dear Timothy,

I created a 2-factor CP model with

`correlatedA = TRUE`

a couple of weeks ago and it went well.Now, I reran the model and received the polite note of changing

`correlatedA`

to`correlatedACE`

, as you just mentioned in your post. Unfortunately, in my case, using`correlatedACE`

does not result in a model with correlated A,C, and E paths. The corresponding paths (a_cp_r2c1/c_cp_r2c1/e_cp_r2c1) do neither show up in the list of parameters nor are they plotted in the model. Do you have any idea to solve this problem?Thank you in advance and best wishes,

Ida

Hi Luis

I don't usually have trouble changing objects within OpenMx models. One difference I notice is that you use:

whereas I would use something like

that is, refer to a matrix with model$matrix without either $submodels or $matrices in the string. I'm not sure that this is your issue though. Another option is to replace the whole matrix

although clumsier, the pass through mxModel has validation checks that can prevent runtime errors. HTH!