Giles Heywood
2005-Jan-09 22:38 UTC
[Rd] S4 class no longer accepts matrix in array slot under 2.0.1
I have an S4 class with a slot of class "array", and in upgrading to 2.0.1 (from 1.9.1) I have encountered a change in behaviour. This causes me some difficulties if I want to allow 2-dimensional arrays in the slot. The following (in 2.0.1) illustrates the point:> setClass("foo",representation("array"))[1] "foo"> a <- new("foo",array(NA,2:4)) > b <- new("foo",matrix(NA,2,3))Error in "as<-"(`*tmp*`, Classi, value = c(NA, NA, NA, NA, NA, NA)) : No method or default for as() replacement of "foo" with Class="matrix" This last error did not occur under 1.9.1. I conclude that in this context the methods package does not recognise "matrix" as a subclass of "array". However if I use getClass(), I see that R recognises "matrix" as a subclass of "array" (and vice-versa). So is this new behaviour correct? [this is a re-posting to R-devel of a question earlier posted to R-help, which attracted limited response]
John Chambers
2005-Jan-10 23:10 UTC
[Rd] S4 class no longer accepts matrix in array slot under 2.0.1
Your example and your subject heading are two different things. If you meant the subject heading, that in fact works. R> setClass("a1", representation(x="array")) [1] "a1" R> new("a1", x=matrix(1:12,3,4)) An object of class "a1" Slot "x": [,1] [,2] [,3] [,4] [1,] 1 4 7 10 [2,] 2 5 8 11 [3,] 3 6 9 12 That's not what your example does. In your example, the new class extends "array", rather than using it as a slot. It would have been clearer if you had said setClass("foo", contains="array"), but your code is correct for that purpose. On first examination, I believe the problem is just what the message says it is. You gave as a new object (and NOT as a slot) an object from a subclass of a superclass of "foo". This is allowed, but has to be done by replacing the part of a "foo" object corresponding to the "array" contained in a "matrix" object. Of course, we know that's actually the whole object, but nothing has told the software this. And, indeed, it doesn't find the necessary replacement method. Here's an example similar to what you are doing, but using actual classes. Barring screwups on my part, it shows that the mechanism works as asserted. Classes "c1", "c2", "c3" follow the roles of "array", "matrix", and "foo" in your example. R> setClass("c1", representation(x="numeric")) [1] "c1" R> setClass("c2", contains="c1") [1] "c2" R> setClass("c3", contains = "c1") [1] "c3" R> x2 = new("c2", x=1) R> x3 = new("c3", x2) R> x3 An object of class "c3" Slot "x": [1] 1 Classes "matrix" and "array" are rather peculiar in R; among other things, they act like vector data types in that is.object() is FALSE. And you cannot have an "array" with a dimension of length 2. R> class(array(1:12, dim=c(3,4))) [1] "matrix" Also, because they don't have a consistent set of "slots" (they may or may not have a "dimnames), they aren't quite real classes in an S4 sense. It would be nice to fix this mess, but not obviously possible while being back compatible. It's possible that there is a fix to get around the particular error here, without breaking the more general pattern--I'll take a look. Otherwise, you may need to follow the approach of your subject heading, and define a new class with an array as a slot. Giles Heywood wrote:> I have an S4 class with a slot of class "array", and in upgrading to 2.0.1 > (from 1.9.1) I have encountered a change in behaviour. This causes me some > difficulties if I want to allow 2-dimensional arrays in the slot. > > The following (in 2.0.1) illustrates the point: > > >>setClass("foo",representation("array")) > > [1] "foo" > >>a <- new("foo",array(NA,2:4)) >>b <- new("foo",matrix(NA,2,3)) > > Error in "as<-"(`*tmp*`, Classi, value = c(NA, NA, NA, NA, NA, NA)) : > No method or default for as() replacement of "foo" with > Class="matrix" > > This last error did not occur under 1.9.1. > > I conclude that in this context the methods package does not recognise > "matrix" as a subclass of "array". However if I use getClass(), I see that R > recognises "matrix" as a subclass of "array" (and vice-versa). So is this > new behaviour correct?You conclude incorrectly, as noted above.> > [this is a re-posting to R-devel of a question earlier posted to R-help, > which attracted limited response] > > ______________________________________________ > R-devel@stat.math.ethz.ch mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >