从NAMESPACE访问S3方法的正确方法

时间:2015-10-05 10:49:53

标签: r

TL; DR版本:

为什么基本R方法的导出方式与Roxygen2作者建议您导出自己的方法的方式不同?

进一步说明:

这是对可以找到herehere的帖子的跟进问题。我认为最好向社区提问,而不是用很多问题轰炸哈德利。

我试图理解S3method导出的行为更好一点,因为基本R方法的导出方式和Roxygen2作者建议他们应该导出的方式之间似乎存在不一致。

例如,stats包中包含plot.tsplot.stepfun方法。您还可以edit()fix()这些。但是,根据推荐的Roxygen2工作方式,建议您@export使用所有泛型和方法(Hadley的回答here)。

所以,假设我们有一个类my_class的对象,我们希望创建一个适用于这个类plot.my_class的绘图函数。我们可以按如下方式创建Roxygen2文档:

#' plot.my_class title
#'
#' @param x An object of class 'my_class'.
#'
#' @export
plot.my_class <- function (x, ...) # some magic

这将生成NAMESPACE条目

S3method(plot,my_class)

现在,当我安装软件包时,当我在plot.my_class中的软件包位置上使用ls()时,我将无法看到方法search(),我也{{1} }或edit()它(我可以使用fix())。显然,这与基本R函数的行为不同,因为我可以getAnywhere()并在edit(plot.ts)包名称空间中列出它。我能看到解决此问题的唯一方法是在我的stats文档中明确@export plot.my_class,例如

Roxygen2

哪会产生 - 明显错误 - #' plot.my_class title #' #' @param x An object of class 'my_class'. #' #' @export plot.my_class plot.my_class <- function (x, ...) # some magic 条目

NAMESPACE

Hadley说使用export(plot.my_class) edit()是一个坏主意。我理解为什么会这样(可能有人可以扩展一点?)但是它们对于调试目的非常有用,因为我正在使用的函数非常复杂。

总而言之,为什么基础R的方法可见的方式和我自己的方法不同?

1 个答案:

答案 0 :(得分:1)

我怀疑它出于同样的原因,基本R包中存在许多其他不一致的地方:它是一个多年来不断发展的有机系统,而且很多方面都非常陈旧并且保持与S语言的兼容性。

roxygen2和其他软件包推荐的许多指南都源于多年与R合作所获得的经验。

如果基本的R软件包今天从头开始重写而不考虑向后兼容性,那么它们看起来会非常不同。

如果您发现自己需要edit和/或fix在其他人的软件包中捣乱,那么这表明这些软件包存在一些应该解决的重大问题。通常你不应该这样做 - 这是为什么fix是一个坏主意的部分原因:它是潜在问题的症状。

事实上,即使使用Hadley推荐的包装泛型出口模式,仍然可以(尽管更难)在包装的非导出方法中进行黑客攻击。