Reputation: 2323
How can I import an S3 method from an R
package without depending on the package when the generic function of the method is not defined in that package?
More specifically, my btergm
package (on CRAN and GitHub) imports several functions from the ergm
package. It also uses the formula
method (defined in ergm
) of the simulate
generic function (defined in the methods
package). I would like to import this method from ergm
. How do I do that?
I have read elsewhere that I could just add a dependency to the ergm
package. But I do not want to move ergm
from Imports:
to Depends:
in the description because the btergm
package defines its own gof
function, while a function with that name is also present in the ergm
package. This would cause a warning that my package overwrites the gof
function after loading ergm
, and CRAN does not like warnings.
It kind of works without the import at the moment. However, the lme4
package also defines a formula
method for the simulate
generic function. If somebody loads lme4
after loading ergm
, the wrong method is picked by my code. Hence the need for a proper import.
The current setup in the description file of the btergm
package:
Imports: stats4, utils, methods, graphics, network (>= 1.13.0), sna (>= 2.3.2), ergm (>= 3.10.0), parallel, Matrix (>= 1.2.2), boot (>= 1.3.17), coda (>= 0.18.1), stats, ROCR (>= 1.0.7), speedglm (>= 0.3.1), igraph (>= 0.7.1), RSiena (>= 1.0.12.232), statnet.common (>= 4.2.0)
Suggests:
fastglm (>= 0.0.1),
testthat
Depends: R (>= 3.5), xergm.common (>= 1.7.7), ggplot2 (>= 2.0.0)
And the relevant part from the namespace file:
import("methods")
...
importFrom("ergm", "ergmMPLE")
importFrom("ergm", "control.simulate.formula")
importFrom("ergm", "remove.offset.formula")
importFrom("ergm", "ergm.getnetwork")
importFrom("ergm", "ergm.getmodel")
importFrom("ergm", "ergm.Cprepare")
importFrom("ergm", "ergm.design")
importFrom("ergm", "ergm.pl")
importFrom("ergm", "control.ergm")
importFrom("ergm", "ergm.getglobalstats")
importFrom("ergm", "ergm.geodistdist")
importFrom("ergm", "ergm")
importFrom("ergm", "mcmc.diagnostics")
In the ergm
package, the namespace export looks as follows:
S3method(simulate,formula)
How do I import this now? Is it importFrom("ergm", "simulate")
or importFrom("ergm", "simulate.formula")
or importFrom("ergm", "formula-method")
or something completely different? The Writing R Extensions section on specifying imports does not say anything about this.
Upvotes: 0
Views: 388
Reputation: 44867
The simulate
generic is actually defined in stats
, not methods
. If you want to make sure the simulate.formula
method from ergm
is found, you need to make sure that the ergm
package is loaded; your other imports from that package will ensure that.
However, if lme4
is loaded later, then its simulate.formula
method will take precedence, and you'll get a message like
> library(lme4)
Loading required package: Matrix
Registered S3 method overwritten by 'lme4':
method from
simulate.formula ergm
If lme4
was loaded first, you'll presumably get a warning when ergm
overwrites its simulate.formula
method, and probably something in lme4
will break.
There's not a lot you can do to prevent this: it's a weakness of the S3 system.
The ideal solution is for the maintainers of stats
(R Core), ergm
(Pavel N. Krivitsky) and lme4
(Ben Bolker) to get together and decide on what simulate.formula
should do, probably putting it in stats
, and one or both of the other packages would then rename their method. That's not likely to be quick.
Another possibility is for you to get the maintainer of ergm
to export the method, so you can call ergm::simulate.formula
explicitly.
For a workaround, you might be able to define your own function using
simulate.formula <- ergm:::simulate.formula
and not export it. Because it looks like a method defined in your own namespace, I think it will have priority over the registered methods, and your code should work. However, you will get a check warning about using :::
; you might be able to get away with this by explaining the need for it in your submission message.
Upvotes: 0