While developing our
agop package I encountered some problems with calling S4 generic functions defined in the
Matrix package, that were created from “base” S3 generics. I don’t know whether it’s an R bug (tested in R 2.15 and R Under development 2013-05-19 3.1-r62765), or whether such behavior was induced intentionally by the R team.
Note that I discuss here package development-related issues, and not the end-user ones.
The scenario was as follows:
- I have a package that Depends on the
- IN the package I created a function that takes an object of class
Matrix) as argument, and calls the S4 generic function (that was my intention)
t(); something like:
- If the function had been created in the global environment, then everything would be OK. In my case, however, I get:
> x1 x2 test1(x2) Error in t.default(x) : argument is not a matrix
Strange, isn’t it?
- The error message indicates that an S3 method was called here (
t.default()). However, in the GlobalEnv, we have:
> body(t) standardGeneric("t") # It's an S4, not S3 generic [defined in the Matrix namespace]
Quite surprisingly (for me),
> body(get('t', envir=baseenv())) UseMethod("t") # the S3 generic from the BaseEnv
Why? My package’s namespace is ABOVE the
The solution is very simple – call the S4 generic by pointing the
Matrix‘s namespace directly with the
Still, however, I’d like to know WHY we have such behavior – any ideas?
Here is an minimal example of a package exploring this issue: NamespaceTest_0.1.tar.gz (run
R CMD INSTALL NamespaceTest_0.1.tar.gz).
@UPDATE: The problem is known (see e.g. this post). Some suggest using
importFrom() in the
NAMESPACE file. However, the above-given solution, IMHO, is much more elegant and straightforward.