当R
包中未定义方法的泛型函数时,如何从 包导入 S3 方法而不依赖于该包?
更具体地说,我的btergm
包(在CRAN和GitHub上)从ergm
包中导入了几个函数。它还使用simulate
泛型函数(在methods
包中定义)的formula
方法(在ergm
中定义)。我想从ergm
导入此方法。我该怎么做?
我在其他地方读到,我可以向ergm
包添加一个依赖项。但我不想在描述中将ergm
从Imports:
移动到Depends:
,因为btergm
包定义了自己的gof
函数,而具有该名称的函数也存在于ergm
包中。这将导致警告我的软件包在加载ergm
后覆盖gof
函数,并且CRAN不喜欢警告。
目前无需导入即可工作。但是,lme4
包还为simulate
泛型函数定义了formula
方法。如果有人在加载ergm
后加载lme4
,我的代码选择了错误的方法。因此,需要适当的进口。
btergm
包描述文件中的当前设置:
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)
以及命名空间文件中的相关部分:
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")
在ergm
包中,命名空间导出如下所示:
S3method(simulate,formula)
我现在如何导入它?是importFrom("ergm", "simulate")
还是importFrom("ergm", "simulate.formula")
或importFrom("ergm", "formula-method")
或完全不同的东西?有关指定导入的"编写 R 扩展"部分对此没有任何说明。
泛型simulate
实际上是在stats
中定义的,而不是在methods
中定义的。 如果要确保找到ergm
中的simulate.formula
方法,则需要确保加载ergm
包;您从该包中导入的其他内容将确保这一点。
但是,如果稍后加载lme4
,则其simulate.formula
方法将优先,并且您将收到类似
> library(lme4)
Loading required package: Matrix
Registered S3 method overwritten by 'lme4':
method from
simulate.formula ergm
如果首先加载lme4
,则当ergm
覆盖其simulate.formula
方法时,您可能会收到警告,并且lme4
中的某些内容可能会中断。
您可以采取很多措施来防止这种情况:这是S3系统的弱点。
理想的解决方案是让stats
(R Core)、ergm
(Pavel N. Krivitsky)和lme4
(Ben Bolker)的维护者聚在一起决定simulate.formula
应该做什么,可能把它放在stats
,然后一个或两个其他包会重命名他们的方法。 这不太可能很快。
另一种可能性是让ergm
的维护者导出方法,这样您就可以显式调用ergm::simulate.formula
。
对于解决方法,您可以使用以下方法定义自己的函数
simulate.formula <- ergm:::simulate.formula
而不是导出它。 因为它看起来像在您自己的命名空间中定义的方法,所以我认为它将优先于注册的方法,并且您的代码应该可以工作。 但是,您将收到有关使用:::
的检查警告;您可以通过在提交消息中解释对它的需求来摆脱这种情况。