在R中,如何从一个包中扩展泛型方法?

sdg*_*sdh 16 generics packages r

我有一个包含PackageA泛型函数的包:

#' doWork
#' 
#' Do some work!
#'
#' @export
setGeneric(
    "doWork", 
    function(x) {

        standardGeneric("doWork")
    })

setMethod(
    "doWork", 
    signature = c("numeric"), 
    definition = function(x) {

        x == 10 # Some logic... 
    }
Run Code Online (Sandbox Code Playgroud)

PackageB,依赖于PackageA,我想添加更多方法doWork:

#' @import PackageA
setMethod(
    "doWork", 
    signature = c("character"), 
    definition = function(x) {

        length(x) == 1 && x == "10" # Some more logic... 
    }
Run Code Online (Sandbox Code Playgroud)

这有效.但是,这意味着用户也PackageB必须library(PackageA).

这失败了:

library(PackageB)

doWork("10") # Fails!
Run Code Online (Sandbox Code Playgroud)

这有效:

library(PackageA)
library(PackageB)

doWork("10")
Run Code Online (Sandbox Code Playgroud)

我想使用from PackageA中的泛型PackageB,但不要求PackageA加载只使用中的方法PackageB.

我怎样才能做到这一点?

sdg*_*sdh 10

这实际上是记录在案的,但不是很清楚; 见1.5.6写作R附加.

诀窍是从中导入通用PackageA,然后从中重新导出PackageB.使用roxygen注释,这看起来像:

#' @importMethodsFrom PackageA doWork
#' @export 
setMethod(
    "doWork", 
    signature = c("character"), 
    definition = function(x) {

        length(x) == 1 && x == "10" # Some more logic... 
    })
Run Code Online (Sandbox Code Playgroud)

当你打电话时devtools::document(),除非你先加载PackageA(通话library(PackageA)),否则这将失败.

但是,一旦建成,PackageA不是必需的:

> library(PackageB)
> showMethods("doWork")
Function: doWork (package PackageA)
x="character"
x="numeric"
Run Code Online (Sandbox Code Playgroud)

作为参考,自动生成的NAMESPACE文件如下所示:

exportMethods(doWork)
importMethodsFrom(PackageA, doWork)
Run Code Online (Sandbox Code Playgroud)

这种方法不会产生关于命名冲突等的警告,所以它似乎是"犹太教".


Bro*_*ieG 5

这似乎对我有用,但是我看不到有文档记录,因此我不一定会认为它是犹太洁食。 pckgA

#' @export

setGeneric("doWork", function(x) standardGeneric("doWork"))
setMethod("doWork", signature = "numeric", function(x) x == 11)
Run Code Online (Sandbox Code Playgroud)

pckgB

#' @export
#' @import pckgA

setGeneric("doWork", getGeneric("doWork", package="pckgA"))
setMethod("doWork", "character", function(x) identical(x, "10"))
Run Code Online (Sandbox Code Playgroud)

主要的窍门是进口和转口doWorkpckgApckgB。然后从一个干净的R会话开始:

library(pckgB)
doWork("10")
# [1] TRUE
doWork("11")
# [1] FALSE
doWork(11)
# [1] TRUE
library(pckgA)
doWork(11)
# [1] TRUE
doWork("10")
# [1] TRUE
Run Code Online (Sandbox Code Playgroud)

您可能需要完全清除工作区(包括隐藏的对象)以摆脱任何先前的方法定义,才能使此方法真正正确地生效。