Hi, I am working on writing some S4 classes that represent multidimensional (brain) image data. I would like these classes to support standard array indexing. I have been studying the Matrix and EBImage (http://www.bioconductor.org/packages/1.9/bioc/html/EBImage.html) packages to see how this is done. When using objects of the "array" class directly, R distinguishes between the calls: x[i,,] and x[i] with the former returning a 2D array of values and the latter returning a single value. The question I have is whether this same behavior can be simulated in classes that do not inherit from the "array" class directly? (See below for a snippet from the EBImage package which suggests that it cannot). My guess is that native array indexing is making use of the information provided by the commas, and this is unavailable to user implemented class methods? thanks, Brad Buchsbaum # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - setMethod("[", signature(x = "Image", i = "numeric", j = "missing"), function(x, i, j, k, ..., drop) { if (missing(k)) { warning("using index [int], cannot distinguish from [int,,ANY], use [int,1:dim(x)[2],ANY] otherwise") tmp = x at .Data[i, drop = FALSE] } else { tmp = x at .Data[i, , k, drop = FALSE] } ... }
Hackish (and maybe expensive; does match.call duplicate the call arguments?), but maybe setClass("A", "numeric") setMethod("[", c(x="A"), function(x, i, j, ..., drop=TRUE) { "..." %in% names(match.call(expand.dots=FALSE)) })> a <- new("A") > a[i][1] FALSE> a[i,,][1] TRUE ? Martin "Bradley Buchsbaum" <bbuchsbaum at berkeley.edu> writes:> Hi, > > I am working on writing some S4 classes that represent > multidimensional (brain) image data. I would like these classes to > support standard array indexing. I have been studying the Matrix and > EBImage (http://www.bioconductor.org/packages/1.9/bioc/html/EBImage.html) > packages to see how this is done. > > When using objects of the "array" class directly, R distinguishes > between the calls: > > x[i,,] and x[i] > > with the former returning a 2D array of values and the latter > returning a single value. The question I have is whether this same > behavior can be simulated in classes that do not inherit from the > "array" class directly? (See below for a snippet from the EBImage > package which suggests that it cannot). > > My guess is that native array indexing is making use of the > information provided by the commas, and this is unavailable to user > implemented class methods? > > thanks, > > Brad Buchsbaum > > > > # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - > setMethod("[", signature(x = "Image", i = "numeric", j = "missing"), > function(x, i, j, k, ..., drop) { > if (missing(k)) { > warning("using index [int], cannot distinguish from > [int,,ANY], use [int,1:dim(x)[2],ANY] otherwise") > tmp = x at .Data[i, drop = FALSE] > } > else { > tmp = x at .Data[i, , k, drop = FALSE] > } > ... > } > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel-- Martin Morgan Bioconductor / Computational Biology http://bioconductor.org
You can find this info using the function nargs(). I've used this with S3 classes, and as far as I know it should work with S4 classes too. See ?nargs for examples. -- Tony Plate Bradley Buchsbaum wrote:> Hi, > > I am working on writing some S4 classes that represent > multidimensional (brain) image data. I would like these classes to > support standard array indexing. I have been studying the Matrix and > EBImage (http://www.bioconductor.org/packages/1.9/bioc/html/EBImage.html) > packages to see how this is done. > > When using objects of the "array" class directly, R distinguishes > between the calls: > > x[i,,] and x[i] > > with the former returning a 2D array of values and the latter > returning a single value. The question I have is whether this same > behavior can be simulated in classes that do not inherit from the > "array" class directly? (See below for a snippet from the EBImage > package which suggests that it cannot). > > My guess is that native array indexing is making use of the > information provided by the commas, and this is unavailable to user > implemented class methods? > > thanks, > > Brad Buchsbaum > > > > # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - > setMethod("[", signature(x = "Image", i = "numeric", j = "missing"), > function(x, i, j, k, ..., drop) { > if (missing(k)) { > warning("using index [int], cannot distinguish from > [int,,ANY], use [int,1:dim(x)[2],ANY] otherwise") > tmp = x at .Data[i, drop = FALSE] > } > else { > tmp = x at .Data[i, , k, drop = FALSE] > } > ... > } > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >
Hi everybody. I myself am not subscribed for Rd therefore replying late. As the author of EBImage, I'd like to comment on the issue. As Tony correctly writes one can generally use nargs() to get the number of arguments, and this works for "["(x,i,j,...,drop) method as well. The problem I had with the EBImage where I could not distinguish between x[index] and x[index,,] is that somehow particularly for the "[" method and particularly for 3 dimensions nargs in both cases gave me the same number of arguments! This behavior was not present when the number of dimension was 2 or 4, i.e. for x[index,] or x[index,,,] -- these could be easily distinguished from x[index]. Anyway, maybe R changed since and I just did not notice that :) Otherwise, coming back to Bradley's original question, it is generally a difficult task to implement correct indexing if your underlying type does not initially support it simply because there are so many combinations possible! Originally, EBImage's Image class was not based on 'array' and then "[" method definitions were simply overwhelming -- too many and too long, and still did not work completely right. Using array simply allowed me to pass the arguments as they are to the underlying array and only build a couple of features on top. It becomes even more difficult for the set method "[<-" as you really need to parse all indexes and make them rotating if too short etc etc. Here the power of R in freestyle indexing of arrays becomes a pain. -- Dr Oleg Sklyar | EBI-EMBL, Cambridge CB10 1SD, UK | +44-1223-494466