[Rd] creating a '[' method for an S4 class
Martin Maechler
maechler at stat.math.ethz.ch
Sat Jul 7 10:20:27 CEST 2012
>>>>> Benilton Carvalho <beniltoncarvalho at gmail.com>
>>>>> on Sat, 7 Jul 2012 03:49:34 +0100 writes:
> Hi,
> I'm working on an S4 class that is expected to behave like an array.
> I have some difficulties when defining '[' and I wonder if someone
> could point me to the right direction:
> 1) Call the S4 object "obj"
> 2) Assume dim(obj) = c(10, 4, 2)
> 3) Suppose someone calls: obj[1:3,] , which is a mistake, given
> dim(obj); how do I detect such situations?
yes, a good question with a tricky answer.
Actually not only relevant for S4, and hence one of the basic
tricks is already visible in [.data.frame :
--- you need to use nargs() in addition to others more well
known tools ---
*and* it is trickier than you think:
Not only want you differentiate between
obj[ i , ]
and
obj[ i , , ]
but more importantly,
between
obj[ i ]
and
obj[ i , ]
and that's where nargs() comes into play
(as 'j', the 2nd argument is missing in both cases, you cannot
use that check alone).
In my CRAN package Rmpfr {Interface R <--> MPFR library for
arbitrary precision arithmetic}
I use S4 classes and methods extensively, as two argument
dispatch is the most natural paradigm for arithmetic.
Here is the part (from Rmpfr/R/array.R )
which implements "[" for 'mpfrArray':
{but you probably want the full package in src to understand all
the details}:
.mpfrA.subset <- function(x,i,j, ..., drop) {
nA <- nargs()
if(getOption("verbose"))
message(sprintf("nargs() == %d mpfrArray indexing ... ", nA))
r <- getD(x)# data part of x, a list()
if(nA == 2) ## A[i]
return(new("mpfr", r[i]))
## else: nA != 2 : nA > 2 -
dim(r) <- (dx <- dim(x))
dimnames(r) <- dimnames(x)
r <- r[i,j, ..., drop=drop]
if(drop && is.null(dim(r)))
new("mpfr", r)
else {
D <- if(is.null(dr <- dim(r))) # ==> drop is FALSE; can this happen?
rep.int(1L, length(r)) else dr
x at Dim <- D
x at Dimnames <- if(is.null(dn <- dimnames(r)))
vector("list", length(D)) else dn
if(length(D) == 2 && class(x) != "mpfrMatrix")
## low-level "coercion" from mpfrArray to *Matrix :
attr(x,"class") <- getClass("mpfrMatrix")@className
attributes(r) <- NULL
setDataPart(x, r, check=FALSE)
}
}
## "["
setMethod("[", signature(x = "mpfrArray", i = "ANY", j = "ANY", drop = "ANY"),
.mpfrA.subset)
## this signature needs a method here, or it triggers the one for "mpfr"
setMethod("[", signature(x = "mpfrArray", i = "ANY", j = "missing",
drop = "missing"),
.mpfrA.subset)
> Thank you very much for your attention and time,
> benilton
More information about the R-devel
mailing list