[Bioc-devel] Making non-bioconductor packages play nice with bioc (and vice versa)

Martin Morgan mtmorgan at fhcrc.org
Mon Sep 5 23:50:17 CEST 2011

Hi Steve --

On 09/05/2011 11:29 AM, Steve Lianoglou wrote:
> Hi,
> I guess this could go here or r-devel, so apologies in advance if
> you'd rather I send the question there.
> I'm helping to develop a package which is outside the bioc universe
> (data.table[1]) which I'm trying to get to play nice with the
> bioc-verse (particularly IRanges), but running into some problems.
> data.table was (and still is) written in using S3, and I've been
> adding some functionality for it to respond to some S4-isms.
> In order to sneak around some limitation of S3's dispatch on
> cbind/rbind, I'm currently experimenting with redefining its cbind and
> rbind functions to use S4 dispatch, but I can't seem to find a way to
> define and export these functions in a way that won't trample IRange's
> cbind/rbind's definitions (or vice versa).
> I've tried to "guard" against an already defined cbind generic (say,
> from IRanges), like:
> if (!isGeneric("cbind")) {
>    setGeneric("cbind", function(..., deparse.level=1)
> standardGeneric("cbind"), signature="...")
> }

I don't really like this idea. It implies you'll take whatever cbind 
comes along, whereas you're really interested in only specific cbinds 
(the one in base, for instance). You've already used a NAMESPACE to 
determine what functions are reliably available, so either there's a 
cbind generic that you're interested in attaching methods to or there 
isn't. Likely you want to promote base cbind to a generic (since as you 
say it doesn't make sense to introduce IRanges as a dependency).


> but exporting cbind from data.table's NAMESPACE will trample the cbind
> methods from IRanges (if IRanges is loaded first). Loading IRanges
> after data.table will hose the cbind/rbind defined in data.table.

Conceptually, and my story might depart from reality here, I'd think 
that data.table::cbind and IRanges::cbind are distinct generics, and 
that when you say 'trample' you mean mask, i.e., IRanges generic and 
methods are still available, just further down the search path than is 
found by default. So the user has to IRanges::cbind or 
data.table::cbind. Within either package, they both know the appropriate 
cbind generic and hence cbind methods, so no need for pkg::cbind. 
Likewise, in a package that import(IRanges, cbind), dispatch within the 
package is un-affected by what data.table does.

> I guess one way to do it is to importFrom(IRanges, cbind, rbind) in
> data.table's NAMESPACE, but it wouldn't really be appropriate to
> introduce an IRanges dependency to data.table.

agreed, this doesn't sound appropriate.

>> From reading through the R-exts doc, I get the feeling that what I'm
> trying to do is not possible, but maybe there's a way for me to do
> this that I'm overlooking?
> Will two different packages that declare and implement S4 functions by
> the same name always trample over one another unless one of them
> imports these functions from the other?
> And a random (somehow related), stylistic question. Out of curiosity:
> why doesn't IRanges "export" rbind,cbind through the exportMethods()
> directive, since its an S4/generic (instead of just export())?

I'm not the author so don't know for sure, and again my story might 
depart from reality. But I think of the setGeneric in IRanges as 
producing a new generic function, and the function is exported. This is 
different from adding methods to an existing, perhaps already visible 
(e.g., 'show') generic.

> Thanks,
> -steve
> [1] data.table: http://cran.r-project.org/web/packages/data.table/index.html

Computational Biology
Fred Hutchinson Cancer Research Center
1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109

Location: M1-B861
Telephone: 206 667-2793

More information about the Bioc-devel mailing list