The correct way to use cbind, rbind with s4 classes in a package

I wrote a package using S4 classes and would like to use rbind, cbind functions with these specific classes.

Since it is not possible to define rbind and cbind directly as S4 methods, I defined rbind2 and cbind2 instead:

 setMethod("rbind2", signature(x="ClassA", y = "ANY"), function(x, y) { # Do stuff ... }) setMethod("cbind2", signature(x="ClassA", y = "ANY"), function(x, y) { # Do stuff ... }) 

From ?cbind2 I found out that these functions need to be activated using methods:::bind_activation to replace rbind and cbind from the database.

I included the call to the R / zzz.R package file using the .onLoad function:

 .onLoad <- function(...) { # Bind activation of cbind(2) and rbind(2) for S4 classes methods:::bind_activation(TRUE) } 

This works as expected. However, performing the R CMD check now I get the following note, since I use an unexported function in the methods:

 * checking dependencies in R code ... NOTE Unexported object imported by a ':::' call: 'methods:::bind_activation' See the note in ?`:::` about the use of this operator. 

How can I get rid of a NOTE and how to correctly define the cbind and rbind methods for S4 classes in a package?

+7
r package s4
source share
1 answer

I think that basically the cBind man page in the Matrix package was accurate historically, but not quite recently. Here is the class

 .A = setClass("A", representation(x="numeric")) 

There is nothing in common, so create it by sending the argument "..." (see ?setMethod and ?dotsMethods )

 getGeneric("cbind") ## NULL setGeneric("cbind", signature="...") ## Creating a new generic function for 'cbind' in the global environment 

Then we implement the method

 setMethod("cbind", "A", function(..., deparse.level=1) "cbind,A-method") ## [1] "cbind" 

And finally use it

 > cbind(.A(), .A()) [1] "cbind,A-method" 

This is great if the arguments "..." are the same (possibly derived) class, which is often quite good.

 > cbind(.A(), integer()) [,1] [1,] ? 

I believe bind_activation() has global effects, and not just from sending in your package; it should be avoided (for example, it is no longer used in the Matrix package).

Also, I think it was updated in R-devel


r67699 | legality | 2015-02-01 10:13:23 -0800 (Sun, Feb 01, 2015) | 4 lines

cbind / rbind is now delegated recursively to cbind2 (rbind2) when at least one argument is an S4 object and sending S3 fails; also consider S4 inheritance while sending S3 in the * bind function.

+4
source share

All Articles