Skip to content

namespace S3 and S4 generic imports cannot both be satisfied:

3 messages · John Chambers, Martin Morgan

#
PkgA wishes to write a method for 'unique' on S4 class 'A'. ?Methods indicates 
that one should

   setGeneric("unique")

   setClass("A")
   unique.A <- function(x, incomparables=FALSE, ...) {}
   setMethod(unique, "A", unique.A)

Both S3 and S4 methods need to be exported in the NAMESPACE

   import(methods)
   S3method(unique, A)
   exportMethods(unique)

PkgB introduces a new class and method

   setClass("B")
   unique.B <- function(x, incomparables=FALSE, ...) {}
   setMethod(unique, "B", unique.B)

and in the NAMESPACE has

   import(methods)
   importFrom(PkgA, unique)
   S3method(unique, B)
   exportMethods(unique)

Unfortuantely, R CMD check says that

* checking whether package 'PkgB' can be installed ... WARNING
Found the following significant warnings:
   Warning: found an S4 version of 'unique' so it has not been imported correctly
See '/home/mtmorgan/tmp/PkgB.Rcheck/00install.out' for details.

This is from (svn r61253) R-devel/src/library/base/R/namespace.R:1339, where the 
code finds the S4 generic, but not the S3 generic. Obviously the namespace 
cannot have both the S3 and S4 symbols defined, but this seems to be required? A 
workaround might extend the check to include getGeneric(genname)@default.

This scenario is reproducible in the attached tarball

   tar xzf PkgAB.tar.gz
   R CMD INSTALL PkgA
   R CMD check PkgB

Martin Morgan
#
Yes, you are right.

Mixing S3 and S4 methods for a generic is fine, although in subtle cases 
one is safer promoting the S3 method to an S4 method, as you did in your 
example.

Usually, the default method for the S4 generic is the S3 generic.  But, 
in general, it's not possible to check algorithmically whether the S3 
methods will be dispatched.  For example, an S4 method on "vector" could 
dispatch S3 methods on subclasses "numeric", etc. (don't ask why ...), 
for a generic that had no default method.

That the trouble with this check isn't found right away is likely 
because one is typically working with a primitive where no generic 
function is created.

Should be fixed in rev. 61263.  Please check on your real example; it 
seems fine on the test you submitted.

Thanks for the catch.

John
On 12/8/12 3:05 PM, Martin Morgan wrote:
4 days later
#
On 12/09/2012 08:27 PM, John Chambers wrote:
Thanks, this addresses the problem for our real example. Martin