From mario.annau at gmail.com  Sat Jan 24 21:02:36 2015
From: mario.annau at gmail.com (Mario Annau)
Date: Sat, 24 Jan 2015 21:02:36 +0100
Subject: [Rd] Proper way to define cbind, rbind for s4 classes in package
In-Reply-To: <CAOQ5NyeRprfmr+RyUxnoz3JCy9jsz+hasWZN0A=KBrRbdkykRw@mail.gmail.com>
References: <54C35EB5.3060402@gmail.com>
	<CAOQ5NyeRprfmr+RyUxnoz3JCy9jsz+hasWZN0A=KBrRbdkykRw@mail.gmail.com>
Message-ID: <54C3FA5C.408@gmail.com>

>> I have written a package using S4 classes and would like to use the
>> functions rbind, cbind with these defined classes.
>>
>> Since it does not seem to be possible to define rbind and cbind directly
>> as S4 methods (see ?cBind) I defined rbind2 and cbind2 instead:
>>
> 
> This needs some clarification. It certainly is possible to define
> cbind and rbind methods. The BiocGenerics package defines generics for
> those and many methods are defined by e.g. S4Vectors, IRanges, etc.
> The issue is that dispatch on "..." is singular, i.e., you can only
> specify one class that all args in "..." must share (potentially
> through inheritance). Thus, trying to combine objects from a different
> hierarchy (or non-S4 objects) will not work. 
This is unfortunately an issue in my case since I would like to dispatch
on different classes.

To be more explicit than in the toy example, my actual method definition
is as follows:

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

The class DataSet actually wraps a pointer to a 2-dimensional HDF5
dataset. To make DataSet extensions more intuitive for the user I
thought that overloading cbind/rbind would be a good idea.

Best,
mario

> I would argue that bind_activation(TRUE) should be discouraged,
> because it replaces the native rbind and cbind with recursive variants
> that are going to cause problems, performance and otherwise. This is
> why it is hidden. Perhaps a reasonable compromise would be for the
> native cbind and rbind to check whether any arguments are S4 and if
> so, resort to recursion. Recursion does seem to be a clean way to
> implement "type promotion", i.e., to answer the question "which type
> should the result be when faced with mixed-type args?".
> 
> Hopefully others have better ideas.
> 
> Michael
> 
> 
> 
> 
>> 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 learned that these functions need to be activated using
>> methods:::bind_activation to replace rbind and cbind from base.
>>
>> I included the call in the package file R/zzz.R 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, running R CMD check I am now getting
>> the following NOTE since I am using an unexported function in 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 the NOTE and what is the proper way to define the
>> methods cbind and rbind for S4 classes in a package?
>>
>> Best,
>> mario
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel



[Rd] Proper way to define cbind, rbind for s4 classes in package
Mario Annau