I’m going to release a new version of cmstatr soon. This new version includes, amongst other things, a new vignette. In R packages, a vignette is a type of long-form documentation. This particular vignette includes a simulation study that helps to demonstrate the validity of a particular statistical method. This simulation study takes a long time to run, though. It takes long enough that I don’t want to sit and wait for it to run every time I check that package, and I don’t want to waste resources on the CRAN servers and force their servers to re-run my vignette every time they check that package.

Jeroen Oorms wrote a blog post at rOpenSci about this topic. I decided to follow the advice in that blog post and pre-compute the new vignette on my computer, and avoid having to re-run it every time the package is checked. The blog post doesn’t include all of the necessary information for vignettes that include graphs, though. This present blog post is intended to fill in that gap.

The basic idea is that you take your long-running vignette and rename it with the extension .Rmd.orig so that R (and CRAN) doesn’t try to build it, because it doesn’t recognize it as an RMarkdown file. Then you write a script that invokes knitr to to run the executable code in the vignette and write a .Rmd file where the code is no longer executable. With this approach, when R tried to re-build the vignette, none of the code is executable, and it runs almost instantly.

In the case of the new vignette being added to cmstatr, the filename of the vignette is hk_ext.Rmd.

The first step is easy. Just rename the vignette from hk_ext.Rmd to hk_ext.Rmd.orig.

If were were to run the function knitr::knit("hk_ext.Rmd.orig", output = "hk_ext.Rmd"), it would create the .Rmd file with the executable code turned into non-executable code, and with the results of the code included. The figures would be located in folder figures/ and referenced by the resulting markdown file. However, the path to figures/ will be relative to the current working directory. This is a problem, since the current working directory will (likely) be the root directory of the package, and the vignettes are stored in the vignettes/ sub-folder.

We can fix this problem by using the following script to re-build the vignette. I’ve saved this script with the very verbose filename rebuild-long-running-vignette.R.

old_wd <- getwd()

setwd("vignettes/")
knitr::knit("hk_ext.Rmd.orig", output = "hk_ext.Rmd")
knitr::purl("hk_ext.Rmd.orig", output = "hk_ext.R")

setwd(old_wd)

This sets the working directory to the vignettes/ sub-folder, rebuilds the vignette then sets the working directory back to what it originally was.

We also need to make a change to the setup chunk of our vignette (hk_ext.Rmd.orig). This will tell knitr to put the resulting figures in the same folder as the vignette, rather than a sub-folder.

knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.path = ""  # Added this line to the standard setup chunk
)

Now to rebuild the vignette, you just run the script rebuild-long-running-vignette.R. This script should be added to .Rbuildignore so that it doesn’t get included in the built package. Similarly, the .Rmd.orig file needs to be added to the .Rbuildignore file.

The other issue is remembering to update the vignette, now that it’s not automatic. I personally use devtools to release packages to CRAN. When you run devtools::release() it asks you a bunch of standard questions. It’s possible to add extra questions according to the documentation. So, I’ve added the following un-exported function to the package:

release_questions <- function() {
  c(
    "Did you re-build the hk_ext.Rmd using `rebuild-long-running-vignette.R`?"
  )
}