r - S4 方法在另一个包中也设置时失败

标签 r s4

当我尝试设置一个也在另一个包中定义的方法时,我遇到了一个奇怪的问题。可以在 here 中找到演示此问题的示例包.

关键是typeof我尝试设置的方法。我使用 setMethod typeof 的函数当我构建包并在一个简单的 S4 类上尝试它时,它会起作用。

x <- new("A", x = 2)
typeof(x)
[1] "typeof was called"
[1] "myClassA"

但是,如果我加载另一个以前也设置过的包 typeof (例如 bigmemory )在加载 s4test 之前package 如果直接调用它会继续正常工作。
library(bigmemory)
library(s4test)
x <- new("A", x = 2)
typeof(x)
[1] "typeof was called"
[1] "myClassA"

但是,如果 typeof方法被另一个方法内部调用(例如 nrow 参见 here )然后它失败并且只返回 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"

最佳答案

胡安·安东尼奥走在正确的轨道上,
但它与Depends无关和 Imports .
答案在 Methods_for_Nongenerics 的文档条目中
(适用于 typeof 因为它不是 base 中的通用函数):

In writing methods for an R package, it's common for these methods to apply to a function (in another package) that is not generic in that package; that is, there are no formal methods for the function in its own package, although it may have S3 methods. The programming in this case involves one extra step, to call setGeneric() to declare that the function is generic in your package.

Calls to the function in your package will then use all methods defined there or in any other loaded package that creates the same generic function. Similarly, calls to the function in those packages will use your methods.

The original version, however, remains non-generic. Calls in that package or in other packages that use that version will not dispatch your methods except for special circumstances...


您可以通过在干净的 R session 中运行以下命令来查看此效果:
environment(typeof)
<environment: namespace:base>

library(s4test)
environment(typeof)
<environment: 0x0000000017ca5e58>
加载包后,typeof功能已通用,
但不是在它的原始环境中。
您还可以看到新泛型环境的封闭环境:
parent.env(environment(typeof))
<environment: namespace:base>
调用函数时,
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"

关于r - S4 方法在另一个包中也设置时失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50952511/

相关文章:

r - 列表中的模型无法预测

r - 如何操作 R 中的 ggplot 以在 lhs 上为角度 = 45 长 x 轴标签留出额外空间?

r - 在 R 中加入不同的 SpatialPolygonsDataFrame 对象时出现问题

r - 在 R 包中定义组通用函数

r - 打印包含 S4 对象列表列的 data.frame

r - tbl_df 在 S4 类中转换为列表

r - 在 S4 对象中使用 S3 类的示例

r - 如何按行进行累积总和?

r - 使用 R,strsplit 如何在要拆分的字符串末尾使用拆分器处理固定元素?

r - S4 泛型中的可选参数