mxCI(..., remove = TRUE)

tbates's picture
Project:OpenMx
Component:Code
Category:feature request
Priority:normal
Assigned:Unassigned
Status:active
Description

Currently users can't remove CIs from models, only add them. Given they can take hours to compute, this can be a hassle.

One way would be to make things like this work:

  model$intervals = NULL
  model$intervals = model$intervals[-3]

An aid to learning would be to add a note to the help about remove = TRUE parameter to mxModel(), which would remove a CI of that name from the model.

newModel = mxModel(oldModel, mxCI("a_r1_c1"), remove = TRUE)

Comments

tbates's picture

#1

I guess it might just be more intuitive in the model editing phase to support the equivalent using $

so

fit_ace$intervals[-"top.e_std"]

executes

fit_ace <- mxModel(fit_ace, mxCI("top.e_std"), remove=T)

nice to warn when the "removed" item never existed

jpritikin's picture

#2

In term of implementation, I think "model$intervals = NULL" is the easiest. I have a patch for that. However, it's somewhat of a hack because "model$intervals = model$intervals[-3]" doesn't work. Only NULL works. If everybody is okay with that, I'll commit it.

mhunter's picture

#3

Users can remove CIs ... just not the way the op wants

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),
      mxPath(from=manifests, arrows=2),
      mxPath(from=latents, arrows=2,
            free=FALSE, values=1.0),
      mxData(cov(demoOneFactor), type="cov",
            numObs=500))
fr <- mxRun(factorModel, intervals=TRUE)
# Ran with no CI because they don't exist
fr$CI
 
#Add CI
f2 <- mxModel(factorModel, mxCI("A[1,6]"))
f2r <- mxRun(f2, intervals=TRUE)
summary(f2r)$CI
 
#Remove CI: f2 has CIs in it but f3 has removed them
f3 <- mxModel(f2, mxCI("A[1,6]"), remove=TRUE)
f3r <- mxRun(f3, intervals=TRUE)
summary(f3r)$CI

So, are you saying you want the $ accessor to also work for setting and removing CIs?

Also as a note, selection with a negative character has never worked for anything to my knowledge in R.

#E.g.
# fit_ace$intervals[-"top.e_std"]
x <- c(a=7, b=15, g=pi)
x[1]
x["a"]
x[-1]
x[-"a"] #Fails

tbates's picture

#4

Yeah, having $ set and get work for CIs would be great, IMHO.

tbates's picture

#5

Two issues
1. remove=TRUE doesn't warn the user when the CI doesn't exist (which is misleading),
2. remove = TRUE only works on items specified the same way.

We don't do any redundancy checking, or unpacking CIs into single parameter requests (the way, say that mxPath() effectively does). So

require(OpenMx)
data(demoOneFactor)
manifests <- names(demoOneFactor)
latents <- c("G")
f1 <- mxModel("One Factor", type="RAM",manifestVars = manifests, latentVars = latents,
      mxPath(from=latents, to=manifests),
      mxPath(from=manifests, arrows=2),
      mxPath(from=latents, arrows=2, free=F, values=1),
      mxData(cov(demoOneFactor), type="cov", numObs=500)
)
 
# Add a CI by bracket address
f2 <- mxModel(f1, mxCI("A[1,6]"))
f2 <- mxRun(f2, intervals=T)
summary(f2)$CI
 
# Remove it
f3 <- mxModel(f2, mxCI("A[1,6]"), remove=T)
f3 <- mxRun(f3, intervals=T)
summary(f3)$CI
 
# Add CIs for all cells of A
f4 <- mxModel(f3, mxCI("A"))
f4 <- mxRun(f4, intervals=T)
summary(f4)$CI
 
# Remove CI A[1,6] (one cell of "A")
f5 <- mxModel(f4, mxCI("A[1,6]"), remove=T) # no warning that this was not found
 
f5 <- mxRun(f5, intervals=T)
 
summary(f5)$CI # still has A[1,6]
                     lbound  estimate    ubound note
One Factor.A[1,6] 0.3679341 0.3971518 0.4290522     
One Factor.A[2,6] 0.4695034 0.5036607 0.5411646     
One Factor.A[3,6] 0.5389614 0.5772409 0.6193343     
One Factor.A[4,6] 0.6578832 0.7027732 0.7522655     
One Factor.A[5,6] 0.7464224 0.7962494 0.8512582     

We can add the same cell three times, with all being computed (yielding an interesting message in summary)

# Add labels to the free column of A
f2$A$labels[1:6,6] = paste0("A_r", 1:6, "c6") # e.g. A[1,6] = label "A_r1c6"
 
# then add the same cell to CI list under three different names
f_duplicates <- mxModel(f2, mxCI(c("A", "A[1,6]", "A_r1c6")))
f_duplicates <- mxRun(f_duplicates, intervals = T)
 
summary(f_duplicates)$CI
     lbound  estimate    ubound note
1 0.3679341 0.3971518 0.4290522     
2 0.3679341 0.3971518 0.4290522     
3 0.4695034 0.5036607 0.5411646     
4 0.5389614 0.5772409 0.6193343     
5 0.6578832 0.7027732 0.7522655     
6 0.7464224 0.7962494 0.8512582     
7 0.3679341 0.3971518 0.4290522     
# Warning message:
#In data.row.names(row.names, rowsi, i) :
#  some row.names duplicated: 7 --> row.names NOT used

Row names not always lost

f_duplicates <- mxModel(f2, mxCI(c("A[1,6]", "A_r1c6")))
f_duplicates <- mxRun(f_duplicates, intervals = T)
summary(f_duplicates)$CI
                     lbound  estimate    ubound note
One Factor.A[1,6] 0.3679341 0.3971518 0.4290522     
A_r1c6            0.3679341 0.3971518 0.4290522