所以我正在使用一个使用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_
,我认为这可能有一些原因。
答案 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
)。