R:在全局环境中从包'base'创建'split'的通用函数

时间:2015-02-04 12:39:31

标签: r generics split s4 r-s3

为简单起见,我将使用以下示例代码:)

我定义了一个S4类test,然后像往常一样我采用setMethod为类split编写通用函数test

# define a S4 class
setClass(
  Class="test",
  representation=representation(
   m = "matrix"
  )
)

# write generic function 'split' for S4 class 'test'
setMethod(f = "split", signature = c("test"), function(x, f) {
  split(x@m, f)
})

# call generic function for test
split(new("test", m=matrix(1:9,3)), c(1,2,3))

运行上面的代码,R命令行将发出如下消息:

  

在全局环境中从包'base'创建'split'的通用函数

然后程序输出如下:

$`1`
[1] 1 4 7

$`2`
[1] 2 5 8

$`3`
[1] 3 6 9

似乎输出正确。但我的问题是如何压制消息:

  

在全局环境中从包'base'创建'split'的通用函数

非常感谢:)

PS: 我发现将S4类split的方法test的定义替换为我们如何实现S3泛型方法的形式,如下所示将消除该消息

split.test <- function(x, f) {
  split(x@m, f)
}

但是,我认为混合S3和S4 是个好主意:)

1 个答案:

答案 0 :(得分:1)

这是S4类的不幸事实。黄金标准通常被称为Matrix软件包。他们还巧妙地避免了这个问题:rownamescolnames(在base中定义)的重载会直接产生相同的警告。但是对这些功能的检查显示它们是dimnames功能的便捷功能:

> colnames
function (x, do.NULL = TRUE, prefix = "col")
{
    if (is.data.frame(x) && do.NULL)
        return(names(x))
    dn <- dimnames(x)
# ...
}
> rownames
function (x, do.NULL = TRUE, prefix = "row")
{
    dn <- dimnames(x)
# ...
}
> dimnames
function (x)  .Primitive("dimnames")

Matrix包通过针对dimnames定义泛型来避免此问题。正如Michael上面评论的那样,最好的选择是重载[运算符,该运算符类似原始的:

> `[`
.Primitive("[")

再次从Matrix包中借用,一个建议是:

setMethod("[", signature(x = "sparseMatrix", i = "missing", j = "index",
             drop = "logical"), 
    function(x, i, j, ..., drop) {
       # add any behavior for ...
       `[`(x@m, i, j, drop=drop)
    }
)

这还使用[运算符从其他通用函数中添加了许多自由行为。