【问题标题】:Import an S3 method from a package that does not define the generic function从未定义泛型函数的包中导入 S3 方法
【发布时间】:2019-11-01 08:54:01
【问题描述】:

当方法的通用函数未在该包中定义时,如何在不依赖包的情况下从R 包中导入 S3 方法?

更具体地说,我的btergm 包(在CRANGitHub 上)从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") 还是完全不同的东西?关于指定导入的Writing R Extensions 部分没有说明这一点。

【问题讨论】:

    标签: r namespaces package


    【解决方案1】:

    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
    

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

    【讨论】:

      猜你喜欢
      • 2020-04-26
      • 2019-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-26
      • 1970-01-01
      • 1970-01-01
      • 2020-05-12
      相关资源
      最近更新 更多