将非S3基本功能重新定义为R包中的S3功能是不好的风格?

时间:2017-02-14 20:58:59

标签: r oop

所以我正在使用一个使用S3类的R包,如果我可以使用sample作为我的一个类的方法,那将是非常好的。但是,base已将sample声明为非S3函数,因此我想知道:

base函数(例如sample)重新定义为S3函数是不好的风格?这可能会让我的包裹用户感到困惑吗?

您可以重新定义sample并保持base功能正常工作的方式是:

sample.default <- base::sample
sample <- function(x, ...) {
  UseMethod("sample")
}
# This allows me to define a new sample method for my_special_class
sample.my_special_class <- function(...) {...}

但我不确定的是,这是否会导致任何问题或命名空间问题,例如,在加载其他软件包时。我还注意到没有多少包重新定义sample,例如,dplyr使用sample_n而igraph使用sample_,我认为这可能有一些原因。

1 个答案:

答案 0 :(得分:9)

它的“风格”是否主要是以意见为基础的。但是编写R扩展,Section 7.1 - Adding new generics告诉您如何添加掩盖基本基础/推荐函数的新泛型。也就是说,您提出的解决方案在该部分明确提醒:

  

...一个包可以接管基础包中的一个函数,并通过类似

的方式使它成为通用的
 foo <- function(object, ...) UseMethod("foo")
 foo.default <- function(object, ...) base::foo(object)
     

本手册的早期版本建议分配foo.default <- base::foo。这不是一个好主意,因为它在安装时捕获基本功能,并且可能会在修补或更新R时更改。

其他人可能遇到的一个问题是,如果另一个包也将summary注册为通用。然后,根据你的包或其他包的包需要决定使用哪个泛型来注册他们的方法。

没有多少包重新定义sample,因为掩盖基本/推荐功能通常不是一个好主意。这样,用户就可以在顶层获得不同的行为,具体取决于您的软件包是否已加载。

您当然希望避免的一件事是在基础/推荐(或高度使用)的包中屏蔽通用。这样做可以防止顶层的方法调度,从而导致期望通用工作的用户感到头痛(例如dplyr::lag)。