How to Properly Document S4 "[" and "[<-" Methods Using Roxygen

How to properly document S4 [ and “[-“ methods using roxygen?

As of roxygen2 >3.0.0, you no longer need work arounds and only need:

#' Extract parts of testClass.
#'
setMethod("[", signature(x = "testClass", i = "ANY", j="ANY"),
function (x, i, j, ..., drop){
print("void function")
}
)

How to properly document S4 methods using roxygen2

Official Support, explained in devtools doc

http://r-pkgs.had.co.nz/man.html#man-classes
(scroll down to the S4 subsection).

The current short example from that page is reproduced in the following (for convenience):

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

The above link very clearly explains S3, S4, and RC support via roxygen/devtools. The explanation there should be considered to supersede the older answer below, which does work for now, but is less clear and more complicated.

The old answer

Here is an example that should work for most S4 methods.

For documenting S4 generics, I find the following three lines necessary in most of my generic headers:

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

Where helloworld-methods is replaced with the_name_of_your_generic-methods. This will be the name of the Rd file that holds the documentation for the generic and all its methods. This naming convention is not required, but common and useful. The @export tag is necessary now that a namespace is required for your package and you want this method to be available to users of your package, not just other methods/functions in your package.

For documenting methods, I find that only 2 lines are necessary, providing the @rdname and @aliases tag. The @rdname statement should match exactly the one for the generic. The @aliases tag must adhere to a naming convention described in the official S4 documentation section of Writing R Extensions.

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

There should be no spaces after the commas in the @aliases name. I don't know the exact rules surrounding when to add ,ANY to the end of the signature list. The pattern seems to be that the number of elements in all @aliases signature lists needs to match the number of elements in the longest signature vector among the methods. In the example below, one of the methods is defined with 2-element signature, and so R CMD check wasn't satisfied with the documentation unless ,ANY was added to the aliases tag of the other methods, even if their signature definition only has one element.

A complete example follows. I built this and it works with no documentation-level warnings from R CMD check testpkg, using a bug-fixed fork of a very recent devel version of roxygen2 (which I have made available). For quick installation of this fork on your system, use library("devtools"); install_github("roxygen", "joey711"). The most recent version of roxygen2 won't work this moment because of a quotation error (described in a separate answer), but I expect this will be incorporated very soon and my fork won't be necessary. For looking at this example in context of the rest of a package, and seeing the resulting documentation (Rd) files, I have made it available as a trivial test package on github called testpkg.

##############################################################
#' 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)
})

This example assumes that you don't need separate method-specific documentation because your methods haven't veered wildly from the behavior one would expect based on the generic doc. There are means in roxygen2 to handle that alternative case using the @usage tag, but the details would be better handled by a separate SO question.

So most of your documentation effort goes into the roxygen header above the generic definition. This has some basis in the code, since the generic should include all specific arguments that appear in any of the subsequently defined methods . Note that arguments that are handled as part of the ... in the argument list are not included and shouldn't be documented specifically, but the ... itself should be documented above the generic as well (see the full example below).

For further details on the basics of documenting functions, there is a wiki in progress, the old roxygen vignette, as well as the roxygen2 development site on github. There is also a SO question on R documentation with Roxygen in general.

Document new S4 method for an existing generic

I found the answer to the problem myself, which runs devtools::check(document = FALSE) without warnings.

#' Plot a new class
#'
#' Dummy text
#'
#' @param x An object of class \code{\link{my_new_class}}.
#' @param y Not used.
#' @param ... Plot parameters forwarded.
#' @return A plot object.
#' @export
methods::setMethod("plot",
c(x="my_new_class", y="missing"),
function(x, y, ...){
new_plot_func(x, ...)
})

Apparently, an unused argument in an existing generic has to be set as "missing" in setMethod.

Roxygen documentation for existing generics

In the end, using explicit @aliases and @docType tags solved the issue for me. My documentation block now looks like this:

#' Show method for objects of class \code{myclass}.
#'
#' @docType methods
#' @name show-myclass
#' @rdname show-myclass
#' @aliases show-myclass show,myclass-method
#'
#' @param x A \code{myclass} object.
#'
#' @export

How to document S4 methods that rely on classes from external packages?

I'll answer my own question for when anyone in the future might face the same issue.

I don't know if this is the best way of doing it, but I found some hints in ?signature-class.

Briefly, next to a slot to hold the class name (.Data) and the argument names (names), the signature class object also has a package slot. This particular slot is not a formal argument of signature() and neither is it of the constructor new("signature", functionDef, ...).

The way around this is to manually build a structure and pass the structure to as(..., "signature"). The documentation doesn't give any errors, the functions still work and I don't need the package names in the import field.

setMethod(
"to_poly",
as(structure(.Data = c("Rle", "missing"),
names = c("object", "selection"),
package = c("S4Vectors", "")),
"signature"),
function(object) {
requireNamespace("S4Vectors", quietly = TRUE)
df <- data.frame(
x = c(1, base::rbind(start(object), end(object)), length(object)),
y = c(0, base::rbind(runValue(object), runValue(object)), 0)
)
df[!duplicated(df),]
}
)

R CMD check warning: Functions/methods with usage in documentation object ... but not in code

The \usage section in the Rd file needs to include the following:

\method{names}{surveydata}(x) <- value

If this is not automatically inserted by the @method line (I presume that will only add \method{names}{surveydata}(x)?) then you need an explicit @usage section that includes the above. Something like

#' @usage \\method{names}{surveydata}(x) <- value

I would also change the @name and @alias sections to refer to the method explicitly not the generic as that will clash with the Rd file in R::base.

Essentially, the warning is coming from the fact that your package doesn't contains a function "names<-" yet you are using this in \usage{}.

How to properly document S4 class slots using Roxygen2?

roxygen2 v4.1+ and Hadley's latest doc for doing this:

http://r-pkgs.had.co.nz/man.html#man-classes

I have not tried it yet for RC, but it works for me for S4 now.

Previously

It looks like S4 class slots are fully supported under Roxygen2 version 3.0+:

http://blog.rstudio.org/2013/12/09/roxygen2-3-0-0/

"document your S4 classes, S4 methods and RC classes with roxygen2 – you can safely remove workarounds that used @alias and @usage, and simply rely on roxygen2 to do the right thing."



Related Topics



Leave a reply



Submit