---
title: "Documenting other objects"
description: > 
  How to document datasets, packages, and the classes,
  generics, and methods of S3, S4, and R6.
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Documenting other objects}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

## Datasets

Datasets are stored in `data/`, not as regular R objects in the package.
This means you need to document them in a slightly different way: instead of documenting the data directly, you quote the dataset's name.

```{r}
#' Prices of over 50,000 round cut diamonds
#'
#' A dataset containing the prices and other attributes of almost 54,000
#'  diamonds. The variables are as follows:
#'
#' @format A data frame with 53940 rows and 10 variables:
#' \describe{
#'   \item{price}{price in US dollars ($326--$18,823)}
#'   \item{carat}{weight of the diamond (0.2--5.01)}
#'   \item{cut}{quality of the cut (Fair, Good, Very Good, Premium, Ideal)}
#'   \item{color}{diamond colour, from D (best) to J (worst)}
#'   \item{clarity}{a measurement of how clear the diamond is (I1 (worst), SI2,
#'     SI1, VS2, VS1, VVS2, VVS1, IF (best))}
#'   \item{x}{length in mm (0--10.74)}
#'   \item{y}{width in mm (0--58.9)}
#'   \item{z}{depth in mm (0--31.8)}
#'   \item{depth}{total depth percentage = z / mean(x, y) = 2 * z / (x + y) (43--79)}
#'   \item{table}{width of top of diamond relative to widest point (43--95)}
#' }
#' 
#' @source {ggplot2} tidyverse R package.
```

Note the use of two additional tags that are particularly useful for documenting data:

-   `@format`, which gives an overview of the structure of the dataset.
    This should include a **definition list** that describes each variable.
    There's currently no way to generate this with Markdown, so this is one of the few places you'll need to Rd markup directly.

-   `@source` where you got the data form, often a URL.

## Packages

As well as documenting every object inside the package, you can also document the package itself by documenting the special sentinel `"_PACKAGE"`.
This automatically includes information parsed from the `DESCRIPTION`, including title, description, list of authors, and useful URLs.

We recommend placing package documentation in `{pkgname}-package.R`, and have `@keywords internal`.
Use `usethis::use_package_doc()` to set up automatically.

Here's an example:

```{r, eval = FALSE}
#' @keywords internal 
"_PACKAGE"
```

Package documentation is a good place to put `# Package options` that documents options used by the package.

Some notes:

-   By default, aliases will be added so that both `?pkgname` and `package?pkgname` will find the package help.
    If there's an existing function called `pkgname`, use `@aliases {pkgname}-package NULL` to override the default.

-   Use `@references` to point to published material about the package that users might find helpful.

## S3

-   S3 **generics** are regular functions, so document them as such.
    If necessary, include a section that provides additional details for developers implementing methods.

-   S3 **classes** have no formal definition, so document the [constructor](https://adv-r.hadley.nz/s3.html#s3-constructor).

-   It is your choice whether or not to document S3 **methods**.
    Generally, it's not necessary to document straightforward methods for common generics like `print()`.
    (You should, however, always `@export` S3 methods, even internal ones).

    If your method is more complicated, you should document it by setting `@rdname` or `@describeIn`.
    For complicated methods, you might document in their own file (i.e. `@name generic.class`; for simpler methods you might document with the generic (i.e. `@rdname generic)`.
    Learn more about these tags in `vignette("reuse")`.

-   Generally, roxygen2 will automatically figure out the generic that the method belongs to, and you should only need to use `@method` if there is ambiguity.
    For example, is `all.equal.data.frame()` the `equal.data.frame` method for `all()`, or the `data.frame` method for `all.equal()`?.
    If this happens to you, disambiguate with (e.g.) `@method all.equal data.frame`.

## S4

S4 **generics** are also functions, so document them as such.

Document **S4 classes** by adding a roxygen block before `setClass()`.
Use `@slot` to document the slots of the class.
Here's a simple example:

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

S4 **methods** are a little more complicated.
Unlike S3 methods, all S4 methods must be documented.
You can document them in three places:

-   In the class.
    Most appropriate if the corresponding generic uses single dispatch and you created the class.

-   In the generic.
    Most appropriate if the generic uses multiple dispatches and you control it.

-   In its own file.
    Most appropriate if the method is complex.
    or the either two options don't apply.

Use either `@rdname` or `@describeIn` to control where method documentation goes.
See the next section for more details.

## R6

-   R6 methods can be documented in-line, i.e. the method's documentation comments come right before the definition of the method.

-   Method documentation can use the `@description`, `@details`, `@param`, `@return` and `@examples` tags.
    These are used to create a subsection for the method, within a separate 'Methods' section.
    All roxygen comment lines of a method documentation must appear after a tag.

-   `@param` tags that appear before the class definition are automatically inherited by all methods, if needed.

-   R6 fields and active bindings can make use of the `@field` tag.
    Their documentation should also be in-line.

-   roxygen2 checks that all public methods, public fields, active bindings and all method arguments are documented, and issues warnings otherwise.

-   To turn off the special handling of R6 classes and go back to the roxygen2 6.x.x behavior, use the `r6 = FALSE` option in `DESCRIPTION`, in the `Roxygen` entry: `Roxygen: list(r6 = FALSE)`.

roxygen2 automatically generates additional sections for an R6 class:

-   A section with information about the superclass(es) of the class, with links.
    In HTML this includes a list of all inherited methods, with links.

-   An 'Examples' section that contains all class and method examples.
    This section is run by `R CMD check`, so method examples must work without errors.

An example from the R6 tutorial:

```{r}
#' R6 Class Representing a Person
#'
#' @description
#' A person has a name and a hair color.
#'
#' @details
#' A person can also greet you.

Person <- R6::R6Class("Person",
public = list(

    #' @field name First or full name of the person.
    name = NULL,

    #' @field hair Hair color of the person.
    hair = NULL,

    #' @description
    #' Create a new person object.
    #' @param name Name.
    #' @param hair Hair color.
    #' @return A new `Person` object.
    initialize = function(name = NA, hair = NA) {
      self$name <- name
      self$hair <- hair
      self$greet()
    },

    #' @description
    #' Change hair color.
    #' @param val New hair color.
    #' @examples
    #' P <- Person("Ann", "black")
    #' P$hair
    #' P$set_hair("red")
    #' P$hair
    set_hair = function(val) {
      self$hair <- val
    },

    #' @description
    #' Say hi.
    greet = function() {
      cat(paste0("Hello, my name is ", self$name, ".\n"))
    }
  )
)
```
