17.9 Special considerations for vignette code

  • A recurring theme is that the R code inside a package needs to be written differently from the code in your analysis scripts and reports. This is true for your functions (Section 7.5), tests (Section 15.2), and examples (Section 17.6), and it’s also true for vignettes. In terms of what you can and cannot do, vignettes are fairly similar to examples, although some of the mechanics differ.

  • Any package used in a vignette must be a formal dependency, i.e. it must be listed in Imports or Suggests in DESCRIPTION. Similar to our stance in tests (Section 12.6.2), our policy is to write vignettes under the assumption that suggested packages will be installed in any context where the vignette is being built (Section 12.6.3). We generally use suggested packages unconditionally in vignettes. But, as with tests, if a package is particularly hard to install, we might make an exception and take extra measures to guard its use.

The main method for controlling evaluation in an .Rmd document is the eval code chunk option, which can be TRUE (the default) or FALSE. Importantly, the value of eval can be the result of evaluating an expression. Here are some relevant examples:

  • eval = requireNamespace(“somedependency”)

  • eval = !identical(Sys.getenv(“SOME_THING_YOU_NEED”), ““)

  • eval = file.exists(“credentials-you-need”)

The eval option can be set for an individual chunk, but in a vignette it’s likely that you’ll want to evaluate most or all of the chunks or practically none of them. In the latter case, you’ll want to use knitr::opts_chunk$set(eval = FALSE) in an early, hidden chunk to make eval = FALSE the default for the remainder of the vignette. You can still override with eval = TRUE in individual chunks.

Here are the first few chunks in a vignette from googlesheets4, which wraps the Google Sheets API. The vignette code can only be run if we are able to decrypt a token that allows us to authenticate with the API. That fact is recorded in can_decrypt, which is then set as the vignette-wide default for eval.

{r setup, include = TRUE}
can_decrypt <- gargle:::secret_can_decrypt("googlesheets4")
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  error = TRUE,
  eval = can_decrypt
)
{r eval = !can_decrypt, comment = NA, include = TRUE}
message("No token available. Code chunks will not be evaluated.")
{r index-auth, include = TRUE, echo = TRUE}
googlesheets4:::gs4_auth_docs()
{r}
library(googlesheets4)
  • Notice the second chunk uses eval = !can_decrypt, which prints an explanatory message for anyone who builds the vignette without the necessary credentials.

The example above shows a few more handy chunk options. Use include = FALSE for chunks that should be evaluated but not seen in the rendered vignette. The echo option controls whether code is printed, in addition to output. Finally, error = TRUE is what allows you to purposefully execute code that could throw an error. The error will appear in the vignette, just as it would for your user, but it won’t prevent the execution of the rest of your vignette’s code, nor will it cause R CMD check to fail. This is something that works much better in a vignette than in an example.

Many other options are described at https://yihui.name/knitr/options.