r - 从未定义泛型函数的包中导入 S3 方法



R包中未定义方法的泛型函数时,如何从 包导入 S3 方法而不依赖于该包?

更具体地说,我的btergm包(在CRAN和GitHub上)从ergm包中导入了几个函数。它还使用simulate泛型函数(在methods包中定义)的formula方法(在ergm中定义)。我想从ergm导入此方法。我该怎么做?

我在其他地方读到,我可以向ergm包添加一个依赖项。但我不想在描述中将ergmImports:移动到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

而不是导出它。 因为它看起来像在您自己的命名空间中定义的方法,所以我认为它将优先于注册的方法,并且您的代码应该可以工作。 但是,您将收到有关使用:::的检查警告;您可以通过在提交消息中解释对它的需求来摆脱这种情况。

最新更新