当我尝试设置一个也在另一个包中定义的方法时,我遇到了一个奇怪的问题.可以在此处找到演示此问题的示例包.
关键是typeof我尝试设置的方法.我使用setMethod函数,typeof当我构建包并在一个简单的S4类上尝试它时,它可以工作.
x <- new("A", x = 2)
typeof(x)
[1] "typeof was called"
[1] "myClassA"
Run Code Online (Sandbox Code Playgroud)
但是,如果我在加载包之前加载另一个先前也设置的包typeof(例如bigmemory),s4test如果直接调用它继续正常工作.
library(bigmemory)
library(s4test)
x <- new("A", x = 2)
typeof(x)
[1] "typeof was called"
[1] "myClassA"
Run Code Online (Sandbox Code Playgroud)
但是,如果该typeof方法是由另一个方法在内部调用的(例如,nrow请参见此处),那么它将失败并且仅返回S4
nrow(x)
[1] "A"
attr(,"package")
[1] "s4test"
Function: typeof (package base)
x="ANY"
x="big.matrix"
x="myClass"
A connection with
description "stdout"
class "terminal"
mode "w"
text "text"
opened "opened"
can read "no"
can write "yes"
[1] "S4"
Run Code Online (Sandbox Code Playgroud)
Depends胡安·安东尼奥走在正确的道路上,但这与和无关Imports。
答案在文档条目中Methods_for_Nongenerics
(适用于,typeof因为它不是 中的通用函数base):
在为 R 包编写方法时,这些方法通常会应用于(在另一个包中)在该包中不通用的函数;也就是说,该函数在其自己的包中没有正式的方法,尽管它可能有 S3 方法。这种情况下的编程涉及一个额外的步骤,即调用 setGeneric() 来声明该函数在您的包中是通用的。
然后,对包中函数的调用将使用其中定义的所有方法或创建相同通用函数的任何其他加载包中定义的方法。同样,对这些包中的函数的调用将使用您的方法。
然而,原始版本仍然是非通用的。除特殊情况外,该包或使用该版本的其他包中的调用不会调度您的方法......
您可以通过在干净的 R 会话中运行以下命令来查看其效果:
environment(typeof)
<environment: namespace:base>
library(s4test)
environment(typeof)
<environment: 0x0000000017ca5e58>
Run Code Online (Sandbox Code Playgroud)
加载包后,该typeof功能已变得通用,但不在其原始环境中。您还可以看到新泛型环境的封闭环境:
parent.env(environment(typeof))
<environment: namespace:base>
Run Code Online (Sandbox Code Playgroud)
当调用函数时,R 首先在当前环境中查找,如果没有找到,则在封闭环境中查找。该nrow函数是包的一部分base(它也不是通用的,尽管这与这里无关),这意味着它会typeof在看到通用函数之前找到自己的非通用函数。
的文档Methods_for_Nongenerics解释了不同的场景,但对于您的情况,您实际上可以执行以下操作:
setMethod('nrow', signature(x="myClass"),
function(x) {
# find the generic version from the global environment and bind it here
typeof <- get("typeof", .GlobalEnv)
switch(typeof(x),
"myClassA" = "A rows",
"myClassB" = "B rows")
}
)
nrow(x)
[1] "typeof was called"
[1] "A rows"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
152 次 |
| 最近记录: |