Reuse Rmd fragments in package vignettes, README, blog posts and more

Use knitr’s “child chunks” to reuse bits of documentation.

R
Tips
R Markdown
Writing
Author

Garrick Aden-Buie

Published

March 5, 2018

Updated on December 4, 2019 with new advice that will most likely satisfy R CMD check.


Jonathan Carroll (@carroll_jono) posted a twitter poll that turned out to be quite interesting this weekend:

Jonathan Carroll (@carroll_jono) March 2, 2018

What I love to see in a README

Personally, I usually find out about a package while browsing GitHub or a blog post that leads me to check out the package on GitHub. So I’m very partial to a highly explanatory README.

When I run into a new package, I’m hoping the README answers the following questions

  1. Why would I want to use this package?
  2. What does it look like to use this package?

So basically: an explanation of the problem the package solves and at least a short introduction to the functions or syntax of the package.

There are a lot of READMEs out there that just answer the first question with a very basic description of the package, or maybe even a detailed overview of the problem the package solves, but they don’t showcase the package in action. I might not be the typical user, but this always seems like a missed opportunity to me.

Of course, writing good documentation is tricky. And considering that a good package also has vignettes, a README, a related (blogdown) blog post, and possibly even a pkgdown site, making sure the documentation is up-to-date in all of these places can put undue burden on the package developers.

Don’t Repeat Yourself, Clone Yourself

In the spirit of Don’t Repeat Yourself and maximizing the potential of knitr and R Markdown – and the fact that you can use R Markdown for all of the above pieces – I remembered recently reading about child documents in knitr.

I posted my idea to Jonathan’s thread and shortly afterwards @BrodieGaslam wrote back with an idea that really makes the best of child documents. Here’s the full idea:

Write repeatable sections in short .Rmd files.

Adapting from Brodie’s vetr package as an example, these files are stored in man/fragments:

vignettes/
├── alike.Rmd
├── styles.css
└── vetr.Rmd
man/
└── fragments/
    ├── declarative-checks.Rmd
    ├── microbenchmark.Rmd
    ├── related-packages.Rmd
    ├── trust-but-verify.Rmd
    ├── valaddin.Rmd
    └── vetting-expressions.Rmd

Notice man/fragments/related-packages.Rmd. It’s a short R Markdown file with a list of (not surprisingly) related packages – the kind of section that might be included in both the package overview vignette and the README.

man/fragments/related-packages.Rmd >

* [`vetr`](https://github.com/brodieG/vetr) by Yours Truly
* [`asserthat`](https://github.com/hadley/assertthat) by Hadley Wickham
* [`assertive`](https://www.r-pkg.org/pkg/assertive) by Richie Cotton
* [`checkmate`](https://github.com/mllg/checkmate) by Michel Lang

The following packages also perform related tasks ...

Caution: If the fragments are stored in a sub-folder of vignettes/, R CMD check may try to render them and can throw an error when they fail to render because they aren’t complete documents.

Reference the repeatable sections using the child chunk option.

knitr provides a child document chunk option that you can use to embed R Markdown from an external file. Anywhere that you would re-use the documentation, you simply include the following, such as in the vetr package vignette. Again, the following are from the vetr package documentation files.

vignettes/vetr.Rmd >

## Alternatives

There are many alternatives available to `vetr`.  We do a survey of the
following in our [parameter validation functions][4] review:

```{r child="../man/fragments/related-packages.Rmd"} `r ''`
```

This R Markdown “chunk” can be used anywhere else you need it, such as in the package README.Rmd file.

README.Rmd >

## Alternatives

There are many alternatives available to `vetr`.  We do a survey of the
following in our [parameter validation functions][5] review:

```{r child="man/fragments/related-packages.Rmd"} `r ''`
```

The major advantage here is to be able to update the documentation in one place and have those changes propagate to “parent” documents. It’s also useful to be able to arrange or choose the content shown in certain places differently depending on the location (or even during editing!). For example, READMEs typically include installation instructions, but these would be redundant if included in the package vignettes.

The above examples can be extended for use in pkgdown articles (which are essentially an extension of vignettes) or for blogdown posts if you develop your package and blog source on the same machine.

Update: December 4, 2019

Maëlle Salmon helpfully pointed out and then tracked down the solution to an issue that may pop up with the method I originally proposed in this post.

Rather than storing your R Markdown fragments in a subfolder in vignettes/, such as vignettes/fragments, they should instead be stored in man/fragments.

I updated the post above to match Maëlle’s advice. Thanks to Maëlle Salmon for the helpful advice that satisfies R CMD Check!


Thanks @BrodieGaslam for the tip and @carroll_jono for kicking off this thread!