Package vignettes

How to build package vignettes with knitr

Since R 3.0.0, non-Sweave vignettes are officially supported. Please see the section "Non-Sweave vignettes" in the manual "Writing R Extensions". Basically what you need to do for Rnw vignettes are:

  1. add %\VignetteEngine{knitr::knitr} to the Rnw source document (note you still need %\VignetteIndexEntry{} as before);
  2. specify VignetteBuilder: knitr in the package DESCRIPTION file;
  3. add Suggests: knitr in DESCRIPTION if knitr is needed only for vignettes;

Then all your Rnw vignettes will be compiled by knitr instead of the default engine Sweave. The vignette engine knitr::knitr is only one of possible engines in knitr. To see all of them, run

names(vignetteEngine(package = 'knitr'))
# for example:
# "knitr::rmarkdown" "knitr::knitr" "knitr::docco_classic" "knitr::docco_linear"
# "knitr::knitr_notangle" ...

The engines with the suffix _notangle have the same weave functions as those without the suffix, but have disabled the tangle function, meaning that there will not be R scripts generated from vignettes during R CMD build or R CMD check. See here for a discussion on why sometimes we may not want to tangle R scripts from vignettes (basically it is redundant for R CMD check to run the same code again after the code has been executed in weave, and currently the inline R code expressions are not included in the tangle output, which can cause problems).

All the document formats that knitr supports can be used for package vignettes (e.g. R Markdown). I have some examples in the knitr package, and many other packages on CRAN also contain knitr vignettes.

Since R 3.1.0, any document that has specified the vignette engine via %\VignetteEngine{} can be compiled through the command line R CMD Sweave. This is not restricted to Sweave documents or R package vignettes.

I really appreciate the generous support by one of the R core members Duncan Murdoch as well as the hard work by Henrik Bengtsson.

STOP reading now if you are using R 3.0.0 or above. The hack described below is no longer recommended.

Currently R can only use Sweave to build package vignettes, so if we want to build vignettes with knitr, we have to use some tricks. One way to do this is through a Makefile, which will be used by R CMD build when building vignettes. In this Makefile, we can set our rules to create the PDF file using a custom tool like knitr.

How knitr's vignette is built

To illustrate that a Makefile is plausible to build a vignette with knitr, this package itself has provided a vignette built with a Makefile.

The basic idea is to use Rscript with an argument -e to execute an R expression, and the R code in the Makefile should be self-explanatory. I followed Ross Ihaka's tutorial and used a variable PDFS in the Makefile, so if you want to build more PDF's, you just add their names to PDFS.

When your vignette is not compatible to Sweave

If you want to use the power of knitr to build vignettes but unfortunately your syntax is not compatible to Sweave, e.g. results="hide" (you should not quote hide in Sweave), you still have even darker tricks to cheat R. I hate to mention this, but that is all due to the restriction of R that vignettes must go through Sweave first anyway. The hint is that you can put a fake vignette which is valid to Sweave, then put a real vignette somewhere else. In the Makefile, you copy the real vignette to ./inst/doc/ and run knitr on it. After that, you restore the fake vignette as if nothing happened.

We have appealed to R core for a few times that package authors should be able to decide how to build their vignettes, but this has not come true. Long live the voodoo!

Markdown vignettes

You do not have to write vignettes in LaTeX; see this post for how to write vignettes easily with markdown.

A few comments

Now I tend not to put the real vignettes in my packages for the reasons below:

  1. It takes more time to check and compile on CRAN; yes I can turn on cache, but the cache files are like pollution to the package source and I want a clean package;
  2. PDF vignettes are often too big compared to other files in the package (e.g. R source code), so I do not want to bring extra burden to our CRAN hosts, knowing that the number of packages has been growing exponentially;
  3. I can keep track of the number of downloads when I put them on Bitbucket whereas I can know little information from CRAN;

So I just went green.

I thank Carl Boettiger, Ross Ihaka and Andrew Redd for their Makefile examples.