如何导出S3方法,以便在命名空间中可用?

时间:2013-08-29 13:36:30

标签: r devtools roxygen2

我正在创建一个包,对于S3方法,我使用

导出它们
##' @method predict myclass
##' @export
predict.myclass <- function(object,...) { }

现在,当我加载包时,predict对类myclass的对象起作用,但不导出函数predict.myclass。在NAMESPACE中,我只获得条目S3method(predict,myclass)。那么有没有办法导出predict.myclass,以便当用户(她)在控制台中写predict.myclass时,用户将获得predict.myclass的代码?

4 个答案:

答案 0 :(得分:9)

我的回答是“不要那样做”。用户可以methods(predict); getAnywhere('predict.myclass')mypackage:::predict.myclass。用户有一个学习曲线,但使用您的方法掌握这一点有助于用户导航所有方法。不导出该方法的原因是它不是直接调用的,它会使搜索路径混乱不必要的符号(在提示符下键入的每个符号,例如ls(),都必须通过查找search()返回的所有环境中的对象,以及像您这样的用户包位于搜索开始和这些常用函数的名称解析之间。)

答案 1 :(得分:8)

如果您想通过S3method自动在export中同时使用NAMESPACEroxygen2指令,则只需添加一个额外的{{1 }}标记更明确。

为说明起见,我创建了一个虚拟包@export。该软件包在exportTest子目录R/中只有一个文件:

print.foo.R

#' Print method for "foo" class #' #' @param x An object of class "foo" #' @param ... Other arguments passed to or from other methods #' #' @export print.foo #' @export print.foo <- function(x, ...) { cat("This is just a dummy function.\n") } 之后,我有以下document()

NAMESPACE

我从Hadley's advice on exporting a non-S3-method function with a . in the name得到这个想法。如果您使用

# Generated by roxygen2: do not edit by hand

S3method(print,foo)
export(print.foo)

对于提供的#' @export function.name ,它明确地使用export()指令。然后,我测试了是否可以将其与更加模糊的function.name标记结合起来以生成@export指令,瞧!可以。

但是,据我所知,在任何地方都没有记载能够一定做到这一点,因此有可能在某些时候停止工作,甚至可能没有警告。如果您想确保该功能存在和/或已记录在某处,则建议使用opening an issue at their GitHub repo

答案 2 :(得分:2)

对于那些迟到的人来说,在较新版本的roxygen(=&gt; 3.0)中,@export标签会自动运行如何处理方法。

来自Generating Rd files小插曲:

  

S3泛型是常规函数,因此请将其记录下来。 S3类没有正式定义,因此记录构造函数。是否记录S3方法是您的选择。您不需要记录print()等简单泛型的方法。如果您的方法更复杂,您应该记录它,以便人们知道参数的作用。在基础R中,您可以找到更复杂方法的文档,例如predict.lm(),predict.glm()和anova.glm()。

     

旧版本的roxygen需要为所有S3方法显式的@method泛型类标记。从3.0.0开始不再需要,因为roxygen2会自动计算出来。如果要升级,请务必删除这些旧标记。只有泛型和类不明确时,自动方法检测才会失败。例如,all.equal.data.frame()是all.data.frame方法的all,或者是all.equal?的data.frame方法。如果发生这种情况,您可以使用(例如)@method all.equal data.frame。

消除歧义

答案 3 :(得分:0)

我完全同意在某些情况下需要导入S3方法,并且我不知道有任何主张要求这样做的自言自语。甚至base包的导出方法也像print.data.frame

也就是说,除了手动修改NAMESPACE文件并添加行之外,我没有找到使用roxygen2的合理解决方案

export(print.myClass)

另一种方法是复制函数:

 print_myClass <- function(x, ...) print.myClass(x, ...)

这两种解决方案都有缺点。前者具有手动编辑NAMESPACE的明显缺点,而后者则带来了混乱。