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
Generate Matrix with Iid Normal Random Variables Using R
Extracting Noun+Noun or (Adj|Noun)+Noun from Text
R Ggplot2: Legend Should Be Discrete and Not Continuous
Ctree() - How to Get the List of Splitting Conditions for Each Terminal Node
Filter Each Column of a Data.Frame Based on a Specific Value
R Shiny Error: Cannot Coerce Type 'Closure' to Vector of Type 'Double'
How to Read CSV Data with Unknown Encoding in R
R Dpylr Select_If with Multiple Conditions
Shiny R Renderplots on the Fly
How to Open an .Xlsb File in R
Basic - T-Test -> Grouping Factor Must Have Exactly 2 Levels
Generating Multidimensional Data
Find Overlapping Dates for Each Id and Create a New Row for the Overlap
R - How to Find Points Within Specific Contour
How to Unscale the Coefficients from an Lmer()-Model Fitted with a Scaled Response