mxPath

23 replies [Last post]
tbates's picture
Offline
Joined: 07/31/2009

topic for discussing mxPath() function

pdeboeck's picture
Offline
Joined: 08/04/2009
New Problem? I recently got

New Problem? I recently got asked about a script that included the following:

mxPath(from=c("helpful","politics","people","perform","jobsat"),
arrows=2,
free=c(FALSE,FALSE,FALSE,FALSE,FALSE),
values=c(0,0,0,0,0),
labels=c(NA,NA,NA,NA,NA)
),

The code produced the error (traced back to the mxPath call posted above):

"Error in strsplit(reference, omxSeparatorChar, fixed = TRUE) :
non-character argument"

I changed "labels=c(NA,NA,NA,NA,NA)" to "labels=as.character(c(NA,NA,NA,NA,NA))" and it looks like things are fine now.

Some sort of change should be made to prevent this, as I don't think most users would think to use as.character().

mspiegel's picture
Offline
Joined: 07/31/2009
My apologies. the labels

My apologies. the labels should be converted into characters behind the scenes. I'll fix that up.

pdeboeck's picture
Offline
Joined: 08/04/2009
Thanks!!

Thanks!!

mspiegel's picture
Offline
Joined: 07/31/2009
mxPath() now checks to make

mxPath() now checks to make sure that the arguments are vectors, except for 'all' which is a single TRUE or FALSE, and then performs type coercing on each vector argument to the appropriate type. This goodness has been checked into revision 781, so it will be included in the next closed beta release, v. 0.1.4.

tbates's picture
Offline
Joined: 07/31/2009
I wonder if we really want to

I wonder if we really want to let this through error checking:

mxPath(
from=c("x","y"),
arrows=2,
free=TRUE,
values=c(1,.1,1),
labels=c("Varx","Vary")
)

It is a typo in the values parameter, which will cause recycling of from and label elements.

I think that (at least when is all=FALSE), that this should cause an error:

e.g.
values = c(1,2,3);
from = c("from1")
to =c("to")

if( length(values) > max( length(from),length(to) )) {
errorString = "values should not be longer than the paths requested in from and to";
}

mspiegel's picture
Offline
Joined: 07/31/2009
Fixed in revision 792.

Fixed in revision 792.

tbates's picture
Offline
Joined: 07/31/2009
Are triangles defined as

Are triangles defined as sinks or sources that are not referred too in either the manifest or latent lists?

That seems to create a code maintenance issue, where typos don't throw errors - the diagram will just create a triangle.

I wonder if it would be better to avoid this by adding a "triangles" (or "means" or...) list?

Also, how is the triangle scaled? Is it again that anything not in the manifest or latents is given ∂2=0, &xhat; = 1

    mxPath(
        from="one",  # not in latents or manifests, ergo triangle?
        to=c("x", "y"),
        arrows=1,
        free=TRUE,
        values=c(1, 1),
        labels=c("meanx", "beta0")
    )

Steve's picture
Offline
Joined: 07/30/2009
This makes sense to me. It

This makes sense to me. It was proposed at one point (perhaps by me and perhaps by someone else). However, it raised the "reserved words" hackles of some of our development team. AFAIR the "one" is-a-reserved-name-for-a-constant proposal was tabled for future discussion.

tbates's picture
Offline
Joined: 07/31/2009
Thanks Steve, So the

Thanks Steve,

So the situation is currently that any source or sink not found in the manifests or latents lists creates a triangle?

Here's a moot:
Add Diamonds and Triangles to the required elements of a pathic model, with defaults of {} so as little as possible breaks.

Rationale: If we have a latents and manifests list, then all the shapes should have lists.

I can see how it would helpful to have "one" (and "ONE" to avoid obfuscated scripts?) as a keyword

PS: this web site doesn't seem to know either unicode or html code for combining diacriticals ☺

mspiegel's picture
Offline
Joined: 07/31/2009
A triangle is made by

A triangle is made by creating a path where the from field is the reserved word "one". Somebody else can fill in the details on how to create a triangle with a weight other than 1. Does putting a value on the path other than 1 do that? See the demo "SimpleRegression_PathCov" for an example.

Steve's picture
Offline
Joined: 07/30/2009
Ah, so this was implemented.

Ah, so this was implemented. I'm glad. No need for "two" or others. "one" is the minimum sufficient reserved word, and it maps onto what at least one beta tester intuitively thought should happen. Cool!

neale's picture
Offline
Joined: 07/31/2009
An alternative to "one" might

An alternative to "one" might be "triangle". Of course one (ugh) doesn't want to multiply reserved words unnecessarily, but "one" might more likely to be used accidentally. It's probably too late now to change things...

mspiegel's picture
Offline
Joined: 07/31/2009
We decided at the last

We decided at the last developer's meeting that we'll implement multiple constants in a RAM style model. The syntax would be another argument to mxModel called 'constants'. Constants will accept a string vector, so the user could specify whatever name for the constants they desired. So mxModel(type = 'RAM', constants = 'one', ...) would replicate the current behavior. mxModel(type = 'RAM', constants = 'triangle', ...) would use the name 'triangle' instead of 'one'. mxModel(type = 'RAM', constants = c('one', 'two', 'three'), ...) would add three constants to the model. This will be implemented only after constant and parameter substitution have been implemented.

mspiegel's picture
Offline
Joined: 07/31/2009
Based on discussion at

Based on discussion at today's developer meeting, a list of constants will be added to RAM style models, such that the user can specify however many constants they would like to use.

tbates's picture
Offline
Joined: 07/31/2009
The path is usually free. So

The path is usually free. So changing the start value can't be the key to setting the value of the triangle.

This resolves another issue though: "one" is already a reserved word, and other random words like "two" would cause an error, as they are not reserved nor in the latents and manifest...

yes!

multiRegModel <- mxModel("Multiple Regression -- Path Specification",type="RAM",
+ mxData(observed=myRegDataRaw, type="raw"),
+ manifestVars=c("x", "y", "z"),
+ # variance paths
+ mxPath(from=c("x", "y", "z"), arrows=2,free=TRUE,values = c(1, 1, 1), labels=c("varx", "residual", "varz")),
+ # covariance of x and z
+ mxPath(from="x",to="z",arrows=2,free=TRUE,values=0.5,labels="covxz"),
+ # regression weights
+ mxPath(from=c("x","z"), to="y",arrows=1,free=TRUE,values=1,labels=c("betax","betaz")),
+ # means and intercepts
+ mxPath(from="two",to=c("x", "y", "z"),arrows=1,free=TRUE,values=c(1, 1), labels=c("meanx", "beta0", "meanz") )
+ ) # close model
Error: The following are neither manifest nor latent variables: 'two'

tbates's picture
Offline
Joined: 07/31/2009
DropPath? Currently, you can

DropPath?

Currently, you can set the fixed and value of an existing path, but you can't delete it, is that the case?

Would there be a benefit to being able to delete paths? Either added in error interactively, or as an alternative to setting them to zero?

neale's picture
Offline
Joined: 07/31/2009
Ordinarily, even a path fixed

Ordinarily, even a path fixed to zero would not need deleting, as it might be usefully resuscitated if it still has a label.

However, for correcting erroneously assigned paths, I am wondering whether setting its label and bounds to NA would effect its deletion... MichaelS/TimB?

tbates's picture
Offline
Joined: 07/31/2009
It's a bit cryptic to

It's a bit cryptic to have

mxPath(from="here", to="there", label=NA)

delete the path, but perhaps not too much so.

tbates's picture
Offline
Joined: 07/31/2009
Currently to change a path,

Currently to change a path, you have to re-specify all elements of it

mxModel(mzModel, mxPath(from="C2", to="bmi2", arrows=1, free=cF, values=0, label="c"))

Should it be possible to target a path by its label, and just update given parameters?

ie.,

mxUpdatePath(label="c", values=0, free=FALSE)

A very handy variant of this would allow regexp in the name, so you could say

mxUpdatePath(label="c.", values=0, free=FALSE)

and update the value and free-state of all matching labelled paths "c1", "c2" etc...

tbates's picture
Offline
Joined: 07/31/2009
For clarification, are these

For clarification, are these two equivalent?

mxModel(mzModel, 
  mxPath(from=c("C1"), to="bmi1", arrows=1, free=FALSE, values=0, label="c"),
  mxPath(from=c("C2"), to="bmi2", arrows=1, free=FALSE, values=0, label="c")
)

and
 
mxModel(mzModel, 
  mxPath(from=c("C1","C2"), to=c("bmi1","bmi2"), arrows=1, free=FALSE, values=0, label="c")
)    

??

Also, are these two equivalent?

mxPath(from=c("C1","C2"), to=c("bmi1","bmi2"), arrows=1, free=FALSE, values=0, label="c")    
 
mxPath(from=c("C1","C2"), to=c("bmi1","bmi2"), arrows=1, free=FALSE, values=c(0), label=c("c"))

mspiegel's picture
Offline
Joined: 07/31/2009
The first pair of statements

The first pair of statements are equivalent. The default mode for mxPath is to match up pairwise the nth argument of the 'from' field with the nth argument of the 'to' field. If one argument is shorter than the other, then the elements of the shorter argument are recycled. This is very Rish behavior. Use the argument all = TRUE in order to get all possible combinations (what's known in set notation as the "cross product" but Steve told me not to use that term).

The second pair of statements are equivalent. foo == c(foo) in R, whenever 'foo' is of type double, logical, integer, or character.

tbates's picture
Offline
Joined: 07/31/2009
a common need is to allow a

a common need is to allow a rnage of things to covary (connect things to each other _excluding_ to themselves)., i.e

mxPath(from=c("a","b", "c", "d"), values=1, all=TRUE)

people would usually want:
a-b
a-c
a-d
b-c
b-d
c-d
(but not a-a, etc)

Is there a shortcut to do that?

tbates's picture
Offline
Joined: 07/31/2009
Thanks: that's nice, and

Thanks: that's nice, and pretty fool-proof. Nice to have the cross-product up one's sleeve also.