playing with this
> mxMatrix("Stand", cov2cor(matrix(c(10,9,9,15), nrow=2)), name="Y")
Error in row(tmp) :
a matrix-like object is required as argument to 'row/col'
In addition: Warning messages:
1: In if (is.na(nrow)) { :
the condition has length > 1 and only the first element will be used
2: In if (nrow != ncol) { :
the condition has length > 1 and only the first element will be used
I wonder if mxMatrix could detect that the input was already a matrix, and not require the nrow and ncol numbers to be specified again?
Check ?mxMatrix, the second argument to the function is the number of rows. We should probably be more robust on bogus input to the function, but for now it's buyer beware. Try "mxMatrix("Stand", values = cov2cor(matrix(c(10,9,9,15), nrow = 2)), name = 'Y')" it works.
Error checking to nrow and ncol arguments of mxMatrix() function added in revision 693.
thanks Mike... followup
mxMatrix("Stand", cov2cor(matrix(c(10,9,9,15), nrow=2)), name="Y")
Error: 'nrow' argument to mxMatrix must be either NA or a single value.
that might be confusing to the user, because nrow looks like it is a single value,
maybe
Error: 'nrow' argument must be either NA or a single value. mxMatrix(type,nrow,ncol, free, values, labels, lbound, ubound, byrow, dimnames, name...)
or
Error: mxMatrix expected argument 2 to be 'nrow': either NA or a single value.
help in time saves 9 (plaintive emails) :-)
Just looking at ?mxMatrix
As this is only ever viewed by people who need help... It would be nice to:
1. Use labels on parameters
2. Use all common parameters? (name = "3*3 symm", byrow=FALSE)
3. Use values that help the user see what is going on
4. Use other common forms: in this case, the lower-only input
5. Show the output
So instead of
s <- mxMatrix(type="Symm", 3, 3,
c(FALSE, TRUE, TRUE, TRUE, FALSE,
TRUE, TRUE, TRUE, FALSE),
c(1, .8, .8, .8, 1, .8, .8, .8, 1),
c(NA, "free1", "free2", "free1", NA,
"free3", "free2", "free3", NA))
How about:
s <- mxMatrix(
type="Symm", ncol=3, byrow= TRUE, name="3*3_symm",
free=c(FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE),
values= c(1, 2, 3, 2, 4, 5, 3, 5, 6),
labels = c(NA, "free1", "free2", "free1", NA, "free3", "free2", "free3", NA)
)
Would be good to include the results, and also a lower-only example
/rant/
Lots of the R documentation has terrible ?help: It's just left to the hapless user to guess that "..." contains critical unmentioned parameters needed to use the function in practice. And the examples often don't get some real task done.
/rant off/
Also in mxMatrix help, how "byrow" applies when only the lower triangle is supplied is not explicitly stated. byrow TRUE for lower is equivalent to byrow=FALSE for upper, so it is important to know which triangle is being treated as the one being filled.
Currently:
"byrow logical. If ‘FALSE’ (default), the ‘values’, ‘free’, ‘labels’, ‘lbound’, and ‘ubound’ matrices are populated by column rather than by row."
I would add:
Note: for symmetrical matrices being passed on one triangle of data, the "byrow" parameter is interpreted as applying to filling the lower triangle.
As of revision 721, the mxMatrix documentation has a discussion about populating the lower triangle for Symm, Stand, Lower, and Sdiag matrices. Also the examples have been revised.
Thanks Mike: Looks good.
PS:
> mxVersion()
[1] "0.1.2-708"
> # current version should be 721
Two suggested changes to mxMatrix:
1) Automatically figure out ncol or nrows from the other information provided. So for example, I had the following:
> U <- mxMatrix( type="Unit", values=rep(1,Number.occasions), ncol=1)
Error in mxMatrix(type = "Unit", values = rep(1, Number.occasions), ncol = 1) : Both nrow and ncol must be specified on a non-square matrix
As the length of values is known, there shouldn't be a need to specify both ncol & nrow.
2) To shorten the code, I've been using arrays for some of my larger and/or more mutable matrices. For example:
This array holds the information for free, values, labels, lbound and ubound. As most of the array is fixed, it is easier (imo) to just specify a handful of elements. Plus, it seems easier to read the information pertaining to a particular element in the matrix.
Instead of having to write:
mxMatrix( type="Full", free=A.info[,,1], labels=A.info[,,3], values=as.numeric(A.info[,,2]),lbound=as.numeric(A.info[,,4]),ubound=as.numeric(A.info[,,5]))
why not an option to say:
mxMatrix( type="Full", completearray=A.info)
The two fold purpose would be to cutdown the mxMatrix command, but also encourage people to not write out every single matrix (i.e., specify an array as above) --- thereby reducing the code and making it easier to read other people's code. The alternative is a page or more of code specifying 5 8x8 matrices in the above example. (I'll be setting bounds in the future, so I'd need all 5 matrices.)
Just some ideas as I've been working with this.
In regards to comment #1: whoops, this was an oversight on our part. I'll place a ticket and get a fix on this. It may take a few days to patch it: with 9 matrix types I've noticed that devilish errors can appear if I'm not careful when making changes (although I guess I only need to patch the non-square matrices).
In regards to comment #2: I am impressed by your array notation to simplify the process of matrix creation. Looks great! However, instead of adding a feature to the mxMatrix() function, why don't you add a function to your scripting library which can make this transformation? Feel free to post the function to the forums once you get it tweaked. I think taking care of missing matrices (putting the right defaults) will be the trickiest part. Use ?mxMatrix to match default values of your function with our function, but you probably know that already.
Added ticket: http://openmx.psyc.virginia.edu/issue/2009/08/relax-nrow-and-ncol-reguirement-full-matrix. I think the patch applies only to Full matrices, see ticket.
If mxMatrix() is invoked when type = 'Full' AND either nrow or ncol is specified AND (values, free, labels, lbound, ubound) are all either vectors or unspecified AND the length of all specified vectors are identical, then a matrix is created.
matrix clone like model clone...
It would be helpful if mxMatrix allowed this
i.e., if the first parameter is an mxMatrix, then the result is a new matrix differing only in the updated features... in this case the same in all but name
There's one important difference between models and matrices: there's nothing in an MxMatrix object that can't be referenced, whereas it is impossible to add new objects to an MxModel simply by using R's Extract referencing. MxMatrix objects are well known entities, as all MxMatrix objects have slots with predetermined ranges of contents (they all have values, labels and free matrices, as well as slots for types and names and such). MxModel objects do not have this property, as they can contain a large collection of named entities.
Don't have the program in front of me, so I apologize of $name is the wrong reference.
In the svn repository, the matrix print routines now show the "@" symbol to remind the user that S4 object slots are accessed by "@"s.
Default labels? base-name plus row and column would be fine.
I think that almost all cells of a matrix will be labeled... but they default to no label.
I guess this can be done with paste()... but it again raises the entry for users, increases user-code complexity. A function would be ok, but that decreases portability.
So it would be very useful if something like labels = "a..." was equivalent to:
labels= c(
"a11", "a12", "a13",
"a21", "a22", "a23",
"a31", "a32", "a33")
i.e., "..." as a shorthand for "label based on this".
If we're allowing users to constrain parameters to equality by giving them the same label, this will lead to some problems. If we automatically generate labels, we have the potential to automatically and accidentally constrain things to equality.
Even if we wanted to do this, we'd have to work out nomenclature. In your example, a111 could mean element 1,1 of matrix a1, or either elements 11,1 or 1,11 in matrix a. We also have to deal with multiple models; copying a matrix with default labels for use in two models currently has no equality expectations (default labels are NA). Your proposal would create equalities by default.
Labels are completely optional, so I like that they are NA by default. If I want labels, I'll put them in. R's Extract functionality allows for me to pull out elements by row and column anyway.
Just a thought on mean structures. I've been obligated to model the means in every model I've run, even though I'm often only interested in the variance/covariance components. I can understand the motivation for forcing mean modeling as the default (I suppose I should always be modeling the mean structures in my data), but in most the models I run, I'm not intersested in means, and it might be nice to have the option of modeling only the variance/covaiance components.
I only bring this up because I feel I'm not the only one in this boat. Most of the models I see other analysts running are devoid of mean models as well, and no other program I've worked with forces mean modeling as its default, so I fear that it may turn off some potential users.
I don't know if it's to late in the game to do address this issue, or if anyone else feels it should be addressed at all, but I thought I'd bring it up and see what others are thinking.
If you wish to just do covariance modeling, then you can just pass covariances to mxData as shown in the example on the front page of the website.
But if you want to run FIML, a model for the means is required. Sorry, but that's the nature of the beast.
There will soon be a slight change to the syntax in order to make this a bit easier for mxPath users. It won't be in Monday's (8/31) release (0.1.3-xxx), but it will likely be in the next release after that. Let us know if you feel it helps.