Here's a way to use roxygen 5.0.0+ to export generic function methods without creating aliases at the same time, so that the methods aren't listed in the index but are still documented properly in the help page of the generic function. The advantages over the method proposed by @Jthorpe are two-fold:
You don't have to manually spell out the calling signature for methods (after all, you've already done so by defining the method in the first place).
The techniques employed are generally useful for manipulating Rd-file structure with roxygen, beyond the facility provided by @
-tags.
First, export your generic/methods in the usual way. Notice that there is no @rdname
, so aliases won't be created.
#' @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"
Next, follow that with a roxygen block for my_generic
. The noteworthy features of this block are: 1) an alias for the generic function will be created (by @name
), but not for any of its methods; 2) the @evalRd
tag (available since roxygen 5.0.0) evaluates its code to create the \usage
part of the Rd file, programatically.
#' My generic function
#'
#' @evalRd rd_s3_usage("my_generic", "default", "numeric")
#' @param x Some object.
#' @param a Some object.
#' @param ... Stuff.
#' @name my_generic
NULL
The function rd_s3_usage()
creates the required \usage
block as an (escaped) string, in the proper format for documenting S3 methods.
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)
#> }
In creating rd_s3_usage()
, I've written helper functions that are more general than the task at hand requires, for these can then be reused (or adapted) in other situations where one wants to generate Rd blocks programmatically.
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(...))
Alas, running R CMD check
still produces the dreaded Objects in \usage without \alias in documentation object 'my_generic'
error. It seems that one must set method aliases to avoid it.
dnorm
appears in the index of the stats package for me – Kei