【问题标题】:How to extend S3 method from another package without loading the package如何在不加载包的情况下从另一个包扩展 S3 方法
【发布时间】:2013-09-02 01:03:24
【问题描述】:

我正在开发一个具有forecast.myclass 功能的包。我希望该功能与forecast 包很好地配合使用。 IE。当forecast 包被加载时,代码forecast(object) 应该从我的包中调用forecast.myclass

由于我只需要包forecast 中的forecast 的通用定义,并且我不使用包forecast 中的任何其他函数,因此我不愿意将它包含在Depends 中。所以我通过以下方式在我的包中定义泛型:

##'
##' @export
forecast <- function(object,...) UseMethod("forecast") 

##' @rdname forecast.midas_r
##' @method forecast midas_r
##' @export
forecast.midas_r <- function(object,newdata=NULL,method=c("static","dynamic"),insample=get_estimation_sample(object),...) {

现在,当包 forecast 未加载时,一切都按预期工作。但是当我加载包forecast 时,不会调用forecast.midas_r,而在执行forecast(object)object 属于midas_r 类。我该如何解决这个问题?

【问题讨论】:

  • 除非您正在记录 forecast.midas_r(您不是),否则您只需要 @S3method(forcast, midas_r) - 这不会创建 Rd 文件,但会将正确的行添加到 NAMESPACE(这是如果您遇到问题,首先要查看)
  • @hadley 我记录了 forecast.midas_r 的方式,forecast 和 forecast.midas_r 共享相同的帮助页面。代码在这里:github.com/mpiktas/midasr/blob/master/R/midas_r_methods.R,从第 279 行开始
  • 这个帖子太老了,没有公认的解决方案,所以我在这里评论以供参考,这个stackoverflow.com/questions/29079179/…似乎解决了这个问题。

标签: r devtools roxygen2


【解决方案1】:

我不确定是否有简单的解决方案。正如其他人所说,使用Depends 来解决这个问题可能最简单,而不是重新定义通用方法。

这是一个对我有用的简单示例。它与您的解决方案基本相同,但声明 @export 意味着您无需手动更新 NAMESPACE 文件。

##' @name mean
##' @export mean.newClass
##' 
##' @method mean newClass
##'
##' @title mean for \code{newClass} object
##' @param x A \code{newClass} object
##' @param ... Additional arguments
##'
mean.newClass <- function(x, ...){
  stopifnot(class(x)=="newClass")
  return(42)
}

然后package.skeleton("newPkg")。将包含上述内容的文件mean.R放在包的目录/R中。

确保你在下一级目录,然后

roxygenize("newPkg", roxygen.dir="newPkg", copy.package=F, unlink.target=F)

现在

library(devtools)
dev_mode(on=TRUE) ### don't want to have to uninstall the package later
install_local("newPkg")
library(newPkg)
x <- c(1,2)
class(x) <- "newClass"
stopifnot(mean(x)==42)
stopifnot(mean(unclass(x))==1.5)

我意识到meanbase 中的一个函数,但我已经测试了它以在其他地方修改泛型函数以赋予它们一个新方法,因此它也应该扩展到您更一般的情况。

【讨论】:

    【解决方案2】:

    这里的问题是您对forecast 泛型的定义掩盖了预测包中的定义,并且您的方法与您的泛型相关联,而不是与预测包泛型相关联;这只是定义同名函数的两个包的一个复杂实例。解决方案是咬紧牙关并依赖:在预测上,或者在命令行并且您的包和预测都附加时完全解析函数mypackage::forecast(),或导入:预测但不使预测通用对最终用户可用除非让它们 require(forecast) (如果 forecast 功能在某种程度上是您的包的外围,这可能是合适的,例如,当以 2D 绘图时以 3D 绘图就足够了)。

    不管怎样,PkgB 中的 S4 方法在从 PkgA 导入的 S4 泛型上定义和导出隐式向用户公开 S4 泛型,因此即使 Imports: PkgA 在 PkgB 的说明文件中指定,该泛型仍然可用.

    【讨论】:

      【解决方案3】:

      一种可能的解决方案是强制导出forecast.midas_r。这意味着每次在check("yourpackagename") 之后手动更新NAMESPACEexport(forecast.midas_r)

      这样做是为了使forecast.midas_r 对包预测可见。如果forecast.midas_r 没有被导出,并且只存在于包的命名空间中,那么当包forecast 被加载时,通用forecast 将被包forecast。因此,当在未知对象上调用 forecast 时,R 会在包 forecast 和一般工作区中查找相应的方法。由于forecast.midas_r 是私有方法,R 没有找到它并产生错误。

      这不是一个完美的解决方案,因为您需要手动更新NAMESPACE,但它仍然是一个解决方案。

      【讨论】:

        猜你喜欢
        • 2015-09-27
        • 1970-01-01
        • 1970-01-01
        • 2010-12-15
        • 1970-01-01
        • 1970-01-01
        • 2016-03-11
        • 1970-01-01
        相关资源
        最近更新 更多