59

我在 SO 和其他地方看到了一些关于在 Roxygen2 的未来版本中应该或将如何完成的讨论。但是,我被困住了。我应该如何使用 Roxygen2 记录 S4 泛型及其方法?全新泛型/方法的工作示例以及扩展基本 S4 泛型的示例将非常有用。我不想为相同泛型的每个 S4 方法制作单独的(大部分)冗余文档。

尽职调查:我找到了“提取”方法的一个有用示例。但是,对于我的问题,它似乎已经过时且不完整。它在类文档中使用 @slot 标记,该标记不再(不再?)支持。它仅显示核心 S4 方法“[”的扩展,而不是包含 S4 泛型文档的完整 Roxygen 示例。

如何使用 roxygen 正确记录 S4“[”和“[<-”方法?

如果我用 title、description 完整记录一个新的 S4 泛型,@param @return @name @aliases @docType @rdname然后只用相应的 记录 S4 方法@name @aliases @docType @rdname,我会收到以下R CMD check警告:

* checking for missing documentation entries ... WARNING
Undocumented S4 methods:
<< long list of apparently undocumented methods. E.g. generic 'plot' and siglist 'myClass1,ANY' >>
All user-level objects in a package (including S4 classes and methods)
should have documentation entries.

乍一看,好像我用 roxygen2 以这种方式记录的 S4 方法都没有真正起作用。然而,到目前为止,我注意到我对核心方法“show”的扩展没有相关的错误,即使它们的记录方式与其他方法完全相同。这是我在其中一种显示方法上方包含的完整 roxygen 文档的示例,它没有生成缺少文档的错误:

#' @name show
#' @aliases show,myClass2-method
#' @docType methods
#' @rdname show-methods

因此,我不知所措。如您所见,我已经包含了R 包手册的 S4 文档部分中描述的 S4 方法的别名约定,即方法应该有一个具有以下名称的别名(不含空格):

generic,signature_list-method.

不知何故,这并没有被完全理解R CMD check

最后,在使用以下命令构建文档后:

library("devtools")
library("roxygen2")
document("mypkgname")
check_doc("mypkgname")

并构建包,我得到了功能文档。特定方法文档中的任何标题都会出现在“描述”字段中,相当尴尬。所以 roxygen2 显然对每个方法的文档做了一些事情,并且走上了正确的轨道。然而,仅仅避免一个大而令人不安的警告是不够的

> R CMD check mypkgname

我查看了 Rd 文件,但我对它们的了解更少,无法快速了解问题所在,而且我无论如何都想知道 roxygen2 解决方案,这样我就不必在每次文档修订后直接操作 Rd 文件。

所以这是一个多部分的问题:

  1. roxygen2 的 S4 通用和 S4 方法文档的当前推荐方法是什么?

  2. 是否有一个很好的例子可以显示完整的细节?

  3. 大多数 S4 方法的文档丢失的警告可能是什么原因和解决方案(即使具有“缺少”文档的方法实际上已经由 roxygen2 解析了它们的文档,并且生成的 Rd 文件至少足以工作在包后R CMD build mypkgname)?

4

2 回答 2

47

官方支持,在 devtools 文档中解释

http://r-pkgs.had.co.nz/man.html#man-classes (向下滚动到S4小节)。

该页面的当前简短示例在以下内容中复制(为方便起见):

#' An S4 class to represent a bank account.
#'
#' @slot balance A length-one numeric vector
Account <- setClass("Account",
  slots = list(balance = "numeric")
)

上面的链接通过 roxygen/devtools 非常清楚地解释了 S3、S4 和 RC 支持。应该考虑那里的解释取代下面的旧答案,该答案目前确实有效,但不太清楚且更复杂。

旧答案

这是一个适用于大多数 S4 方法的示例。

为了记录 S4 泛型,我发现在我的大多数泛型标题中需要以下三行:

#' @export
#' @docType methods
#' @rdname helloworld-methods

在哪里helloworld-methods替换为the_name_of_your_generic-methods. 这将是包含泛型及其所有方法的文档的 Rd 文件的名称。此命名约定不是必需的,但常见且有用。@export既然您的包需要命名空间,并且您希望此方法对您的包的用户可用,而不仅仅是包中的其他方法/功能,那么该标签是必需的。

对于记录方法,我发现只需要 2 行,提供@rdnameand@aliases标记。该@rdname声明应与泛型的声明完全匹配。该@aliases标记必须遵守编写 R 扩展的官方 S4 文档部分中描述的命名约定。

#' @rdname helloworld-methods
#' @aliases helloworld,character,ANY-method

名称中的逗号后不应有空格@aliases。我不知道何时添加,ANY到签名列表末尾的确切规则。模式似乎是所有@aliases签名列表中的元素数量需要与方法中最长的签名向量中的元素数量相匹配。在下面的示例中,其中一个方法是使用 2 元素签名定义的,因此R CMD check除非将其添加到其他方法的别名标记中,否则对文档不满意,ANY,即使它们的签名定义只有一个元素。

下面是一个完整的例子。我构建了这个,它使用roxygen2 的最新开发版本(我已经提供)R CMD check testpkg的错误修复分支,它在没有文档级别警告的情况下工作。要在您的系统上快速安装此 fork,请使用. 由于引用错误(在单独的答案中描述),最新版本的 roxygen2 目前无法工作,但我希望这将很快被合并,并且我的 fork 将不是必需的。为了在包的其余部分的上下文中查看此示例,并查看生成的文档 (Rd) 文件,我已将其作为 github 上名为testpkg的简单测试包提供。library("devtools"); install_github("roxygen", "joey711")

##############################################################
#' The title, in this case: Helloworld-ify the argument.
#'
#' Some additional details about this S4 generic and its methods.
#' The extra blank line between this section and the title is
#' critical for roxygen2 to differentiate the title from the
#' description section.
#'
#' @param x Description of \code{x}. The main argument in this
#'  example. Most often has such and such properties.
#'
#' @param y Description of \code{y}. An argument that is rarely
#'  used by \code{"helloworld"} methods. 
#'
#' @param ... Additional argument list that might not ever
#'  be used.
#'
#' @return A helloworld-ified argument. Oh, you'll see.
#' 
#' @seealso \code{\link{print}} and \code{\link{cat}}
#' 
#' @export
#' @docType methods
#' @rdname helloworld-methods
#'
#' @examples
#' helloworld("thisismystring")
#' helloworld(char2helloworld("thisismystring"))
#' helloworld(matrix(0,3,3))
#' helloworld(list(0,0,0))
#' helloworld(integer(0))
setGeneric("helloworld", function(x, y, ...){
    cat("Hello World!")
    cat("\n")
    standardGeneric("helloworld")
})

#' @rdname helloworld-methods
#' @aliases helloworld,ANY,ANY-method
setMethod("helloworld", "ANY", function(x, y, ...){
    cat(class(x))
})

#' @rdname helloworld-methods
#' @aliases helloworld,character,ANY-method
setMethod("helloworld", "character", function(x){
    show(x)
})

#' @rdname helloworld-methods
#' @aliases helloworld,character,character-method
setMethod("helloworld", c("character", "character"), function(x, y){
    show(x)
})

此示例假定您不需要单独的特定于方法的文档,因为您的方法并未完全偏离基于通用文档所期望的行为。roxygen2 中有一些方法可以使用@usage标签来处理这种替代情况,但细节最好由单独的 SO 问题处理。

因此,您的大部分文档工作都进入了通用定义上方的 roxygen 标头。这在代码中有一些基础,因为泛型应该包括出现在任何随后定义的方法中的所有特定参数。请注意,作为...参数列表中的一部分处理的参数不包括在内,也不应专门记录,但其...本身也应记录在泛型之上(请参阅下面的完整示例)。

有关记录功能的基础知识的更多详细信息,有一个wiki 正在进行中,旧的 roxygen vignette以及github 上的 roxygen2 开发站点一般来说,关于 Roxygen 的 R 文档还有一个SO 问题。

于 2011-09-14T22:20:08.783 回答
9

我发现第 (3) 部分的答案——S4 方法的不那么缺失的文档——是因为使用 S4 命名约定时,在 \alias 标记周围错误地添加了引号;很可能是由于对包含逗号作为其名称一部分的别名进行文本处理而导致的错误。在本文发布时,最新版本的 roxygen2 仍然如此。我刚刚在 roxygen2 github 页面上通过一个可重现的示例发布了对该错误的更全面的描述:

https://github.com/klutometis/roxygen/issues/40

简要地,

#' @aliases show,helloworld-method

变成

\alias{"show,helloworld-method"}

在生成的 Rd 文件中。删除引号会删除R CMD check警告,并且文档在这两种情况下都会构建并正常运行。

我认为这个问题的第 (1) 和 (2) 部分(最佳实践;很好的例子)仍然开放。

于 2011-09-13T06:50:23.733 回答