314

For documenting classes with roxygen(2), specifying a title and description/details appears to be the same as for functions, methods, data, etc. However, slots and inheritance are their own sort of animal. What is the best practice -- current or planned -- for documenting S4 classes in roxygen2?

Due Diligence:

I found mention of an @slot tag in early descriptions of roxygen. A 2008 R-forge mailing list post seems to indicate that this is dead, and there is no support for @slot in roxygen:

Is this true of roxygen2? The previously-mentioned post suggests a user should instead make their own itemized list with LaTeX markup. E.g. a new S4 class that extends the "character" class would be coded and documented like this:

#' The title for my S4 class that extends \code{"character"} class.
#'
#' Some details about this class and my plans for it in the body.
#'
#' \describe{
#'    \item{myslot1}{A logical keeping track of something.}
#'
#'    \item{myslot2}{An integer specifying something else.}
#' 
#'    \item{myslot3}{A data.frame holding some data.}
#'  }
#' @name mynewclass-class
#' @rdname mynewclass-class
#' @exportClass mynewclass
setClass("mynewclass",
    representation(myslot1="logical",
        myslot2="integer",
        myslot3="data.frame"),
    contains = "character"
)

However, although this works, this \describe , \item approach for documenting the slots seems inconsistent with the rest of roxygen(2), in that there are no @-delimited tags and slots could go undocumented with no objection from roxygenize(). It also says nothing about a consistent way to document inheritance of the class being defined. I imagine dependency still generally works fine (if a particular slot requires a non-base class from another package) using the @import tag.

So, to summarize, what is the current best-practice for roxygen(2) slots?

There seem to be three options to consider at the moment:

  • A -- Itemized list (as example above).
  • B -- @slot ... but with extra tags/implementation I missed. I was unable to get @slot to work with roxygen / roxygen2 in versions where it was included as a replacement for the itemized list in the example above. Again, the example above does work with roxygen(2).
  • C -- Some alternative tag for specifying slots, like @param, that would accomplish the same thing.

I'm borrowing/extending this question from a post I made to the roxygen2 development page on github.

user227710
  • 3,164
  • 18
  • 35
Paul 'Joey' McMurdie
  • 7,295
  • 5
  • 37
  • 41
  • 18
    `@slot` is probably what you want long term, but it has to be implemented first... – hadley Sep 14 '11 at 01:16
  • 3
    Thanks! That's good to know. I'm glad my code has many fewer `setClass` statements than `setMethod`. Making the change once `@slot` is implemented won't be too painful. – Paul 'Joey' McMurdie Sep 14 '11 at 22:46
  • 8
    Some discussion on @slot: https://github.com/klutometis/roxygen/pull/85 – Brian Diggs Mar 21 '12 at 16:39
  • Related question : http://stackoverflow.com/questions/13642092/whats-the-recommended-package-build-workflow-with-packages-that-contain-s4-clas – Joris Meys Nov 30 '12 at 10:54
  • 2
    S4 Classes are now fully supported in Roxygen2 version 3 (available on [github](https://github.com/klutometis/roxygen/releases/tag/v3.0.0)). – Gregor Thomas Dec 09 '13 at 17:21

3 Answers3

33

Updated answer for Roxygen2 5.0.1, current as of 7.2.0

For S4, the best practice now is documenting using the @slot tag:

#' The title for my S4 class that extends \code{"character"} class.
#'
#' Some details about this class and my plans for it in the body.
#'
#' @slot myslot1 A logical keeping track of something.
#' @slot myslot2 An integer specifying something else.
#' @slot myslot3 A data.frame holding some data.
#'
#' @name mynewclass-class
#' @rdname mynewclass-class
#' @export

On a sidenote, @exportClass is only necessary in some cases, the general way to export a function is using @export now. You also don't have to export a class, unless you want other packages to be able to extend the class.

See also http://r-pkgs.had.co.nz/namespace.html#exports

Updated answer for Roygen2 3.0.0, current as of 5.0.1.

For S4, the best practice is documentation in the form:

#'  \section{Slots}{
#'    \describe{
#'      \item{\code{a}:}{Object of class \code{"numeric"}.}
#'      \item{\code{b}:}{Object of class \code{"character"}.}
#'    }
#'  }

This is consistent with the internal representation of slots as a list inside the object. As you point out, this syntax is different than other lines, and we may hope for a more robust solution in the future that incorporates knowledge of inheritance -- but today that does not exist.

As pointed out by @Brian Diggs, this feature was pulled into 3.0.0, further discussion at https://github.com/klutometis/roxygen/pull/85

Serenthia
  • 1,222
  • 4
  • 22
  • 40
William Entriken
  • 37,208
  • 23
  • 149
  • 195
  • 3
    Have you used the implementation by @Brian Diggs? Does it work? Do you think you could provide some details about that approach (and therefore something akin to an `@slot` solution). I haven't gotten around to trying it, waiting (perhaps lazily) for this pending `@slot` solution. I know that is not how the question is posed, but based on comments (including @hadley's) it seems `@slot` is the "real" answer. I agree with your assessment that an itemized list (as in my question) is the current best practice, though hopefully replaced very soon. – Paul 'Joey' McMurdie Jun 08 '12 at 22:23
20

The solution provided by Full Decent is OK if you go for documenting slots in the Rd files itself. When using roxygen2, you can use the tag @section to do basically the same with \describe. An example:

#' The EXAMPLE class
#'
#' This class contains an example. This line goes into the description
#'
#' This line and the next ones go into the details.
#' This line thus appears in the details as well.
#'
#'@section Slots: 
#'  \describe{
#'    \item{\code{slot1}:}{Matrix of class \code{"numeric"}, containing data from slot1}
#'    \item{\code{slot2}:}{Object of class \code{"character"}, containing data that needs to go in slot2.}
#'  }
#'
#' @note You can still add notes
#' @name EXAMPLE 
#' @rdname EXAMPLE
#' @aliases EXAMPLE-class
#' @exportClass EXAMPLE
#' @author Joris Meys
Joris Meys
  • 106,551
  • 31
  • 221
  • 263
16

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."

Paul 'Joey' McMurdie
  • 7,295
  • 5
  • 37
  • 41