Roxygen:如何在不混乱帮助索引的情况下记录方法?
我试图将方法记录在与泛型相同的文件中。我希望Roxygen:如何在不混乱帮助索引的情况下记录方法?,r,roxygen2,R,Roxygen2,我试图将方法记录在与泛型相同的文件中。我希望用法部分包含该方法,但不希望为该方法生成别名。这是因为我有很多泛型方法,我希望保持索引相对干净 我尝试了@rdname和@descripebein两种方法,但这两种方法似乎都会自动生成一个\alias标记,然后显示在索引中。我可以通过手动编辑Rd文件并删除\alias{}条目来获得所需的结果,但这并不是真正可持续的 更新:刚刚从R CMD检查中注意到以下内容: 具有\用法项的函数需要具有适当的\别名 条目,并记录其所有参数 所以也许我要找的东西甚至不合
用法
部分包含该方法,但不希望为该方法生成别名。这是因为我有很多泛型方法,我希望保持索引相对干净
我尝试了@rdname
和@descripebein
两种方法,但这两种方法似乎都会自动生成一个\alias
标记,然后显示在索引中。我可以通过手动编辑Rd
文件并删除\alias{}
条目来获得所需的结果,但这并不是真正可持续的
更新:刚刚从R CMD检查中注意到以下内容:
具有\用法项的函数需要具有适当的\别名
条目,并记录其所有参数
所以也许我要找的东西甚至不合法。你可以使用多行@useage,比如:
#' a generic called foo
#'
#' @param x the only named parameter
#'
#' @usage
#' # you can call `foo()` this way
#' foo(x, ..., [n, ybar,])
#' # or this way
#' foo(x, ..., na.rm = FALSE, details = FALSE)
#' # or even this way
#' foo(x, ..., [n, ybar,] na.rm = FALSE, details = FALSE)
foo <- function(x,...)
return('hello world')
不幸的是,这确实会在R CMD检查中引发一些警告:
* checking for code/documentation mismatches ... WARNING
Codoc mismatches from documentation object 'foo':
foo
Code: function(x, ...)
Docs: function(x, ..., na.rm = FALSE, details = FALSE)
Argument names in docs not in code:
na.rm details
* checking Rd \usage sections ... WARNING
Undocumented arguments in documentation object 'foo'
'...' 'na.rm' 'details'
Bad \usage lines found in documentation object 'foo':
foo(x, ..., [n, ybar,])
foo(x, ..., [n, ybar,] na.rm = FALSE, details = FALSE)
Functions with \usage entries need to have the appropriate \alias
entries, and all their arguments documented.
The \usage entries must correspond to syntactically valid R code.
See the chapter 'Writing R documentation files' in the 'Writing R
这里有一种方法可以使用roxygen 5.0.0+导出通用函数方法,而无需同时创建别名,这样这些方法就不会在索引中列出,但仍然可以在通用函数的帮助页面中正确记录。与@Jthorpe提出的方法相比,该方法有两个优点:
您不必手动拼写方法的调用签名(毕竟,您已经通过首先定义方法来完成了)
所采用的技术通常适用于使用roxygen操作Rd文件结构,超出了@
-标记提供的功能
首先,以通常的方式导出泛型/方法。请注意,没有@rdname
,因此不会创建别名
#' @export
my_generic <- function(x, ...) UseMethod("my_generic")
#' @export
my_generic.default <- function(x, a = NULL, ...) "Default method"
#' @export
my_generic.numeric <- function(x, a = 0, ...) "Numeric method"
函数rd\u s3\u usage()
将所需的\usage
块创建为一个(转义)字符串,格式正确,用于记录s3方法
cat(rd_s3_usage("my_generic", "default", "numeric"))
#> \usage{
#> my_generic(x, \dots)
#>
#> \method{my_generic}{default}(x, a = NULL, \dots)
#>
#> \method{my_generic}{numeric}(x, a = 0, \dots)
#> }
在创建rd\u s3\u usage()
时,我编写了比手头的任务更通用的帮助函数,因为这些函数可以在希望以编程方式生成rd块的其他情况下重用(或调整)
rd_dots <- function(x) gsub("\\.\\.\\.", "\\\\dots", x)
# Figure out calling signature of a function (given by name)
call_sig <- function(nm, cmd = nm, ...) {
f <- get(nm, mode = "function", ...)
sig <- deparse(call("function", formals(f), quote(expr = )))
sig <- paste(trimws(sig, which = "left"), collapse = "")
sig <- sub("^function", cmd, trimws(sig, which = "both"))
rd_dots(sig)
}
# Make a vector of \usage{} entries for an S3 generic
s3_methods <- function(generic, ...) {
classes <- list(...)
rd_tmpl <- sprintf("\\\\method{%s}{%%s}", generic)
cs_methods <- vapply(classes, function(cls) {
method <- paste(generic, cls, sep = ".")
rd_cmd <- sprintf(rd_tmpl, cls)
call_sig(method, rd_cmd)
}, character(1))
c(call_sig(generic), cs_methods)
}
# Rd command markup
rd_markup <- function(cmd, join, sep) {
force(join); force(sep)
rd_cmd_opening <- paste0("\\", cmd, "{")
function(x)
paste(rd_cmd_opening, paste(x, collapse = join), "}", sep = sep)
}
rd_s3_usage <- function(...)
rd_markup("usage", join = "\n\n", sep = "\n")(s3_methods(...))
所有的方法索引项突然消失了。我不知道我做了什么不同。不管怎样,他们在重新安装后回来了。S3还是S4?这很重要。就我所知,这是没有办法的。每个有文档记录的函数都必须列在别名中,每个别名都列在索引中。但也许你的想法是错误的——索引的要点是全面的。我认为担心文件凌乱是没有意义的。谢谢,这肯定比手动编辑文件(+1)要好;根据您的经验,这是否通过R CMD检查?不幸的是,这确实会在R CMD检查中引发一些警告(请参见编辑)。我只在我的工作组中共享的包上使用过这种文档样式,而在CRAN上没有。我想,如果您显式地为S3方法#@usage\n
,多行用法语句可能仍然有效,这可能会阻止关于带有\usage条目的函数的警告需要有适当的\alias条目,并记录它们的所有参数
。那将是我的下一次尝试,但我现在没有时间亲自尝试。谢谢你的帮助。我将暂时不回答这个问题,以防有人提出不同的想法。这必须是可能的,因为t.test的文档正是这样做的。Rd文件中的每个方法都有一个别名,但它们没有列在索引中。但这怎么可能实现呢?谢谢,这看起来很酷。当我在我的项目中回到这个问题时,我会尝试一下。
cat(rd_s3_usage("my_generic", "default", "numeric"))
#> \usage{
#> my_generic(x, \dots)
#>
#> \method{my_generic}{default}(x, a = NULL, \dots)
#>
#> \method{my_generic}{numeric}(x, a = 0, \dots)
#> }
rd_dots <- function(x) gsub("\\.\\.\\.", "\\\\dots", x)
# Figure out calling signature of a function (given by name)
call_sig <- function(nm, cmd = nm, ...) {
f <- get(nm, mode = "function", ...)
sig <- deparse(call("function", formals(f), quote(expr = )))
sig <- paste(trimws(sig, which = "left"), collapse = "")
sig <- sub("^function", cmd, trimws(sig, which = "both"))
rd_dots(sig)
}
# Make a vector of \usage{} entries for an S3 generic
s3_methods <- function(generic, ...) {
classes <- list(...)
rd_tmpl <- sprintf("\\\\method{%s}{%%s}", generic)
cs_methods <- vapply(classes, function(cls) {
method <- paste(generic, cls, sep = ".")
rd_cmd <- sprintf(rd_tmpl, cls)
call_sig(method, rd_cmd)
}, character(1))
c(call_sig(generic), cs_methods)
}
# Rd command markup
rd_markup <- function(cmd, join, sep) {
force(join); force(sep)
rd_cmd_opening <- paste0("\\", cmd, "{")
function(x)
paste(rd_cmd_opening, paste(x, collapse = join), "}", sep = sep)
}
rd_s3_usage <- function(...)
rd_markup("usage", join = "\n\n", sep = "\n")(s3_methods(...))