[Rd] method dispatch and in-place modification? - unclass, RemoveClass, getDataPart, method dispatch

Hin-Tak Leung hin-tak.leung at cimr.cam.ac.uk
Mon Feb 27 13:28:23 CET 2006

I have a little problem about method dispatch and "unnessary" copying.
Basically what I would like to do is:

`[.myclass` <- function(x, i,j, extraopt=TRUE/FALSE, drop=TRUE) {
   ...do stuff depending on extraopt...
    value <- Nextmethod("[", x, i,j, drop=TRUE)
   ... do more stuff depending on extraopt...

I have two general problems:
(1) NextMethod() really doesn't like having "extraopt" around.
(2) I can do "unclass" or "class<-" (they seems to do exactly the
same thing with R_set_class()), but it makes a new copy of the object.
The object in my case is very large - (about 80MB, and will be 10x
higher if I can get away with it) and the copying itself accounts
for 97% of the total CPU time consumed - which basically makes it
about 30 times slower than it should be.
In fact R_set_class says:

> /* set the class to value, and return the modified object.  This is
>    NOT a primitive assignment operator , because there is no code in R
>    that changes type in place. See the definition of "class<-" in 
>    the methods package for the use of this code. */

I came upon "RemoveClass()" in R/src/main/object.c which says it is 
__unused__ but seems to do what I would like it to do.

So I tried a S4 method dispatch mechanism, but it is 3 times *slower*
than unclass, and it seems to be due to the switch() statement inside
  getDataPart() (in R/src/library/methods/R/RClassUtils.R)
which typically copies the object three times? (I think 
"attributes(value) <- NULL" also copies)

> getDataPart <- 
> function (object)
> {
>     ...
>     switch(dataPart, 
>  array = {
>             value <- object
>             attributes(value) <- NULL
>             attr(value, "dim") <- attr(object, "dim")
>             attr(value, "dimnames") <- attr(object, "dimnames")
>             object <- value
>         }, 
>     ...
>     object
> }

The basic question is - is there a way of implementing a method which 
has extra arguments compared to generic? The other question concerns
the "there is no code in R that changes type in place" statement -
how can one avoid excessive copying in these two cases? Is it alright to 
invoke the "RemoveClass()" routine to do a unclass_in_place()?
(I did think about doing my own unclass(), but it just seems exactly 
like what RemoveClass() is!).

Hin-Tak Leung

More information about the R-devel mailing list