使用包装泛型是否要求包装为Depends或Imports?

时间:2015-03-16 14:22:05

标签: r

首先,我已经阅读了很多这个话题。我研究过对话herehereherehere。但问题是,我仍然认为没有完全讨论某个特定主题。我正在开发一个包,我希望使用autoplot()包中的ggplot2泛型创建我自己的方法,即具有autoplot.MyFunction()等函数。

我当前的DESCRIPTION文件包含Depends: ggplot2,一切正常,没问题。我还将此功能与我的函数帮助文件代码中的Roxygen2代码@import ggplot2结合使用,并与@export结合使用。

但是,大多数文档都描述了如何使用Imports: ggplot2。问题是,如果我进行此更改,当我使用library(my_package)加载我的包并尝试使用autoplot.MyFunction()时,我面临以下错误:

> autoplot(tmp)
Error: could not find function "autoplot"

同样,如果我直接调用该函数......

> autoplot.MyFunction(tmp)
Error: could not find function "autoplot.MyFunction"

但是,如果我使用::方法,那么它确实有用......

> ggplot2::autoplot(tmp)

根据我的理解,这是因为Imports 加载 ggplot2包(因此其功能),但不附加它,而Depends 附加它。

所以,最后,我的问题很简单,我认为使用包装泛型是正确的,我应该使用Depends: package,即在我的情况下Depends: ggplot2

然后,为了在我的包函数中使用包中的函数,我应该使用Imports: package加上::,例如:

silly_fn <- function (data) {
  p <- ggplot(tmp, aes(x, y)) + 
    geom_line() + 
    geom_segment(aes(x = 0, xend = 20, y = 0, yend = 20), 
                 arrow = grid::arrow(length = grid::unit(0.15, "inches")))
  p
}

需要Imports: grid和Roxygen2代码@import grid

我认为这是正确的吗?

1 个答案:

答案 0 :(得分:2)

我不是一个完整的专家,但这里有用的东西:

#' @importFrom ggplot2 autoplot
#' @export autoplot

autoplot <- autoplot

#' @export "autoplot.foo"

autoplot.foo <- function(obj, ...) {
  cat("bar\n")
}

不幸的是我们需要显式导出该方法,因为由于某种原因,从包命名空间(在这种情况下为ggplot2)中发送S3并不能找到从包中注册的方法,它不会导入从。这种做法是有道理的,除了它适用于基本泛型,因此我注意到了S3注册机制的微妙之处。

重新判断是否在您的软件包中使用::,这是有争议的。如果您使用@import@importFrom,则不必如此,但有些人(包括哈德利)建议您应该清楚明白。我个人建议反对它,因为R profiler不能解析样式package::method的函数名称,这使得优化代码变得更加困难(有可以满足这两个目标的解决方法)。

请注意,您绝对应该使用@import而不仅仅依赖于::(您还必须更新DESCRIPTION文件)。如果不这样做,将阻止R意识到依赖性。我很确定R CMD check对此大吼大叫。