Iago Mosqueira
2005-Feb-17 12:33 UTC
[Rd] Subsetting using dimnames on S4 array-based class
Hello, I did send this message to r-help and got no reply, no I am resubmitting here in case this was a bit too specific for the other list. Many thanks, Iago From: Iago Mosqueira <imosqueira@suk.azti.es> To: r-help@stat.math.ethz.ch Subject: Subsetting using dimnames on S4 array-based class Date: Fri, 11 Feb 2005 08:29:03 +0000 Hello, I am encountering some problems when overloading the "[" operator for a new S4 class based on array. This is an example class definition: setClass("foo", representation("array"), prototype(array(NA, dim=c(3,3)), dimnames=list(age=1:3, year=10:12)) ) And this the corresponding setMethod with print estatements to see what is being passed: setMethod("[", signature(x="foo"), function(x, i="missing", j="missing", ..., drop="missing") { print(paste("i:", i)) print(paste("j:", j)) } ) So I first create a new object and load it with some data:> x <- new("foo") > x[,] <- 1:9And then apply subsetting without using the dimension names and see what are the values of i and j inside the function:> x[1:2,'10'][1] "i: 1" "i: 2" [1] "j: 10" Both i and j hold exactly what was expected here. But if I use the dimension names, the subsetting indices does not seem to be passed as I expected:> x[age=1:3, year=1:3][1] "i: missing" [1] "j: missing"> x[, year='10'][1] "i: missing" [1] "j: missing" Subsetting with dimnames appears to work without trouble on an array, which "foo" extends: s<-array(1:9,dim=c(3,3),dimnames=list(age=1:3,year=1:3))> s[1,2:3]2 3 4 7> s[age=1,year=2:3]2 3 4 7 Although dimnames seem to be in fact simply ignored:> s[a=1,b=3][1] 7 System: Linux Debian 3.0 R 2.0.0 Do I need to define my class differently for subsetting using dimnames to work? Even if they are not really being checked, I would like to be able to use subsetting in this way as it makes code more readable when using arrays with many dimensions. Many thanks, Iago Mosqueira
Prof Brian Ripley
2005-Feb-17 13:32 UTC
[Rd] Subsetting using dimnames on S4 array-based class
On Thu, 17 Feb 2005, Iago Mosqueira wrote:> I did send this message to r-help and got no reply, no I am resubmitting > here in case this was a bit too specific for the other list.Do read the posting guide before posting, as we ask. It has clear guidelines on this. Your problem seems to be that you want to use named arguments in subscripting (not really anything to do with your subject: using dimnames is like s["row 1", "col 2"] and you are talking about *names of* dimnames). It `works' for arrays because the definition there (in ?Extract) is not the same as the generic you are using: notice the ... in the definitions, and for arrays it is really "["(x, ..., drop=TRUE) and the names of ... are ignored. In brief: this is not how [ in R works. Be careful: m <- matrix(1:6, 2, 3) M <- data.frame(a=1:2, b=3:4, c=5:6) m[j=2, i=1] # 2 M[j=2, i=1] # 3 so argument names are ignored for the primitives, but not for S3 methods (and I believe not for S4 methods).> From: > Iago Mosqueira > <imosqueira@suk.azti.es> > To: > r-help@stat.math.ethz.ch > Subject: > Subsetting using dimnames on S4 > array-based class > Date: > Fri, 11 Feb 2005 08:29:03 +0000 > > Hello, > > I am encountering some problems when overloading the "[" operator for a > new S4 class based on array. This is an example class definition: > > setClass("foo", > representation("array"), > prototype(array(NA, dim=c(3,3)), > dimnames=list(age=1:3, year=10:12)) > ) > > And this the corresponding setMethod with print estatements to see what > is being passed: > > setMethod("[", signature(x="foo"), > function(x, i="missing", j="missing", ..., drop="missing") { > print(paste("i:", i)) > print(paste("j:", j)) > } > ) > > > So I first create a new object and load it with some data: > >> x <- new("foo") >> x[,] <- 1:9 > > And then apply subsetting without using the dimension names and see what > are the values of i and j inside the function: > >> x[1:2,'10'] > [1] "i: 1" "i: 2" > [1] "j: 10" > > > Both i and j hold exactly what was expected here. But if I use the > dimension names, the subsetting indices does not seem to be passed as I > expected: > >> x[age=1:3, year=1:3] > [1] "i: missing" > [1] "j: missing" >> x[, year='10'] > [1] "i: missing" > [1] "j: missing" > > Subsetting with dimnames appears to work without trouble on an array, > which "foo" extends: > > s<-array(1:9,dim=c(3,3),dimnames=list(age=1:3,year=1:3)) >> s[1,2:3] > 2 3 > 4 7 >> s[age=1,year=2:3] > 2 3 > 4 7 > > Although dimnames seem to be in fact simply ignored: > >> s[a=1,b=3] > [1] 7 > > > System: > Linux Debian 3.0 > R 2.0.0 > > Do I need to define my class differently for subsetting using dimnames > to work? Even if they are not really being checked, I would like to be > able to use subsetting in this way as it makes code more readable when > using arrays with many dimensions.-- Brian D. Ripley, ripley@stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595