Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add examples for @rdname to 'reuse' vignette #1496

Merged
merged 4 commits into from
Nov 14, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 54 additions & 27 deletions vignettes/reuse.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -35,40 +35,63 @@ You can document multiple functions in the same file by using either `@rdname` o
It's a technique best used with care: documenting too many functions in one place leads to confusion.
Use it when all functions have the same (or very similar) arguments.

### `@describeIn`
### `@rdname`

Use `@describeIn <destination> <description>` to document multiple functions together.
It generates a new section named "**Related functions and methods**", further divided into subsections by the type of relationship between the source and the destination documentation.
Each subsection contains a bulleted list describing the function with the specified `<description>`.
Use `@rdname <destination>` to include multiple functions in the same page.
Tags (e.g. `@title`, `@description`, `@examples`) will be combined, across blocks but often this yields text that is hard to understand.
So we recommend that you make one block that contains the title, description, common parameters, examples and so on, and then only document individual parameters in the other blocks.

You can document several functions which perform slight variations of a task or which use different defaults in one documentation file:
There are two basic ways to do that.
You can create a standalone documentation block and then add the functions to it.
This typically works best when you have a family of related functions and you want to link to that family from other functions (i.e. `trig` in the examples below).

```{r}
#' Power
#' @param x base
#' @param exp exponent
power <- function(x, exp) x ^ exp
#' Trigonometric approximations
#' @param x Input, in radians.
#' @name trig
NULL

#' @rdname trig
#' @export
sin_ish <- function(x) x - x^3 / 6

#' @rdname trig
#' @export
cos_ish <- function(x) 1 - x^2 / 2

#' @rdname trig
#' @export
tan_ish <- function(x) x + x^3 / 3
```

#' @describeIn power Square a number
square <- function(x) power(x, 2)
Alternatively, you can add docs to an existing function.
This tends to work better if you have a "primary" function with some variants or some helpers.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we're quite there yet, now we have in @rdname

This tends to work better if you have a "primary" function with some variants or some helpers.

Vs in @describeIn

You can document several functions which perform slight variations of a task or which use different defaults

Do we need to distinguish these two "variant"/'variation" use cases further? Or are they ~somewhat~ interchangeable?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBH I've mostly forgotten what @describeIn does and why you might use it. I think the main difference is that it attempts to build the single description for you by creating a bulleted list. But I'm not sure this is now possible to do in a compelling way, and I think you're generally better off using @rdname with a custom @description.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That seems reasonable enough to me. OTOH, as someone looking at a lot of other peoples' code, it's something I come across fairly often -- it would be nice to point to a canonical reference during code review urging one or the other in each case.

I see 1000s of usages on CRAN:

https://github.com/search?q=lang%3AR+%2F%23%27%5Cs%40describeIn%2F+org%3Acran&type=code

Here's the only file with usage in tidyverse:

https://github.com/tidyverse/reprex/blob/b904f73989583e66cb02fd0199df6cede5be1c3f/R/reprex-undo.R#L22

Vs. 10 packages using it from r-lib:

https://github.com/search?q=lang%3AR+%2F%23%27%5Cs%40describeIn%2F+org%3Ar-lib&type=code

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I've made it more clear that I don't recommend it, and I'll fix the reprex usage momentarily.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


#' @describeIn power Cube a number
cube <- function(x) power(x, 3)
```
```{r}
#' Logarithms
#'
#' @param x A numeric vector
#' @export
log <- function(x, base) ...

In this case, both destination and source are "normal" functions, and you can use `<description>` to explain their differences.
#' @rdname log
#' @export
log2 <- function(x) log(x, 2)

`@describeIn` is also well suited to explain the relationships between functions making up an object oriented (OO) scheme using S3 or S4.
In this case, roxygen will automatically detect whether a source function is a method and document the relationship to the relevant class or generic.
Your new methods will be organised in one of two ways:
#' @rdname log
#' @export
ln <- function(x) log(x, exp(1))
```

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need #' @export tags in the next section (L94-103)?

1. If your new method extends a generic in the `<destination>`, it will be listed in a section titled "**Methods for generic `<destination>`**".
The subsection will include all methods for your new generic, labelled by the class they cover.
### `@describeIn`

2. If your new method extends another generic, for a class constructed in the destination, it will be listed in a subsection titled "**Methods for class `<destination>`**".
It will be labelled by the generic which the method extends.
An alternative to `@rdname` is `@describeIn`.
It has a slightly different syntax because as well as a topic name, you also provide a brief description for the function, like `@describein topic one sentence description`.
The primary difference between `@rdname` and `@describeIn`, is that `@describeIn` creates a new section containing a bulleted list all of each function, along with its description.
It uses a number of heuristics to determine the heading of this section, depending on you're documenting related functions, methods for a generic, or methods for a class.

While you can mix and match (some) different types of functions with `@describeIn`, the output may quickly become disorienting for users if the functions are not tightly related.
In general, I no longer recommend `@describeIn` because I don't think the heuristics it uses are as good as a thoughtful hand-crafted summary.
If you're currently using `@describeIn`, you can general replace it with `@rdname`, as long as you give some thought to the multiple-function `@description`.

### Order of includes

Expand Down Expand Up @@ -172,8 +195,10 @@ Note that the evaluation environment is deliberately a child of the package that

You can use the same `.Rmd` or `.md` document in the documentation, `README.Rmd`, and vignettes by using child documents:

```{r child = "common.Rmd"}`r ''`
```
````
```{r child = "common.Rmd"}`r ''`
```
````

The included Rmd file can have roxygen Markdown-style links to other help topics.
E.g. `[roxygen2::roxygenize()]` will link to the manual page of the `roxygenize` function in roxygen2.
Expand All @@ -184,9 +209,11 @@ A workaround is to specify external HTML links for them.
These external locations will *not* be used for the manual which instead always links to the help topics in the manual.
Example:

See also the [roxygen2::roxygenize()] function.
```
See also the [roxygen2::roxygenize()] function.

[roxygen2::roxygenize()]: https://roxygen2.r-lib.org/reference/roxygenize.html
[roxygen2::roxygenize()]: https://roxygen2.r-lib.org/reference/roxygenize.html
```

This example will link to the supplied URLs in HTML / Markdown files and it will link to the `roxygenize` help topic in the manual.

Expand Down
Loading