Creating accessible & reproducible teaching materials with bookdown

Clement Lee

2023-12-08

When inheriting a module

Usual file structure

  • Some .tex files & the generated .pdf
    • verbatim R code & output in .tex
  • figures/ or graphics/:
    • generated for \includegraphics in .tex
    • .eps, .ps, .png, .jpg, .pdf, .gif
  • R-related files:
    • .R that generates the output & figures
    • .RData, .rds, .Rd
  • “By-products”:
    • .out, .log, .dvi, .blg, .bbl, .aux, .synctex.gz
  • Miscellaneous:
    • .csv, .txt, .stan, .sty
    • .pdf of scanned solutions
  • But no README
    • maybe a makefile

 

\(~\)

Scope

A single set of source scripts

  • Code + text combined
    • Reproducible
    • No more separate R scripts
  • Both HTML & PDF outputs
    • Accessible
    • Alternative to Chirun
  • Both questions/gaps & solutions
    • A parameter that toggles between the two
  • Script-based
    • Easy to version control
    • As little scaffolding as possible
  • Language agnostic
    • Less painful to switch from R to Python?
  • Initial time cost
    • Lower priority
    • Focus on future savings

 

This talk

  1. R Markdown basics
  2. Bookdown for notes
  3. Practical considerations

1. R Markdown basics

LaTeX

 

The output (.pdf)

  • \(\pi=3.1415927\dots\) is irrational & transcendental
  • Type pi in R console for numerical value

\(\quad\)

## [1] 6.283185

\(\quad\)
Question: Show that \(e^{i\pi}+1=0\).
Solution: \[\begin{align*} e^{i\pi}+1&=\cos\pi+i\sin\pi+1\qquad\qquad\qquad\qquad\\ &=-1+i\times0+1=0 \end{align*}\]

R Sweave

 

The output (.pdf)

  • \(\pi=3.1415927\dots\) is irrational & transcendental
  • Type pi in R console for numerical value

\(\quad\)

## [1] 6.283185

\(\quad\)
Question: Show that \(e^{i\pi}+1=0\).
Solution: \[\begin{align*} e^{i\pi}+1&=\cos\pi+i\sin\pi+1\qquad\qquad\qquad\qquad\\ &=-1+i\times0+1=0 \end{align*}\]

R Markdown

 

The output (.pdf / .html)

  • \(\pi=3.1415927\dots\) is irrational & transcendental
  • Type pi in R console for numerical value

\(\quad\)

## [1] 6.283185

\(\quad\)
Question: Show that \(e^{i\pi}+1=0\).
Solution: \[\begin{align*} e^{i\pi}+1&=\cos\pi+i\sin\pi+1\qquad\qquad\qquad\qquad\\ &=-1+i\times0+1=0 \end{align*}\]

Chunk options

For displaying / hiding code / plots

 

The output (.pdf / .html)

Chunk options

 

The output (.pdf / .html)

Chunk options

Don’t evaluate

Also useful when showing code that doesn’t work

 

The output (.pdf / .html)

Chunk options

 

The output (.pdf / .html)

Chunk options

Hide the code & results (but still evaluate)

 

The output (.pdf / .html)

Toggle for questions & solutions

 

The output (.pdf / .html)

  1. Plot the cars dataset in R.

  2. Find the numerical value of \(2\pi\), to 4 decimal places.

Toggle for questions & solutions

 

The output (.pdf / .html)

  1. Plot the cars dataset in R.

  1. Find the numerical value of \(2\pi\), to 4 decimal places.
## [1] 6.2832

Parametrise the toggle

 

\(~\)

One script to render them all

 

\(~\)

What about text & equations?

 

The output (.pdf / .html)

Question: Show that \(e^{i\pi}+1=0\).

Solution: \[\begin{align*} e^{i\pi}+1&=\cos\pi+i\sin\pi+1\\ &=-1+i\times0+1=0 \end{align*}\]

What about text & equations?

 

The output (.pdf / .html)

Question: Show that \(e^{i\pi}+1=0\).

Solution: \[\begin{align*} e^{i\pi}+1&=\cos\pi+i\sin\pi+1\\ &=-1+i\times0+1=0 \end{align*}\]

What about text & equations?

 

The output (.pdf / .html)

Question: Show that \(e^{i\pi}+1=0\).

Full example, the questions

 

The output (Practical1_questions.html)
\(\qquad\)
\(\qquad\)
\(\qquad\qquad\) MAS9999 Practical 1

  1. Write R code to plot the cars dataset.

  2. Find the numerical value of \(2\pi\), to 4 decimal places.

  3. Show that \(e^{i\pi}+1=0\).

Full example, the solutions

 

The output (Practical1_solutions.html)
\(\qquad\)
\(\qquad\)
\(\qquad\qquad\) MAS9999 Practical 1

  1. Write R code to plot the cars dataset.
  1. Find the numerical value of \(2\pi\), to 4 decimal places.
## [1] 6.2832
  1. Show that \(e^{i\pi}+1=0\).
    Solution: \[\begin{align*} e^{i\pi}+1&=\cos\pi+i\sin\pi+1\\ &=-1+i\times0+1=0 \end{align*}\]

Language agnostic(-ish)

 

The output (Practical1_solutions.html)
\(\qquad\)
\(\qquad\)
\(\qquad\qquad\) MAS9999 Practical 1

  1. Write R code to plot the cars dataset.
  1. Find the numerical value of \(2\pi\), to 4 decimal places.
## 6.2832
  1. Show that \(e^{i\pi}+1=0\).
    Solution: \[\begin{align*} e^{i\pi}+1&=\cos\pi+i\sin\pi+1\\ &=-1+i\times0+1=0 \end{align*}\]

Quarto

 

The output (Practical1_solutions.html)
\(\qquad\)
\(\qquad\)
\(\qquad\qquad\) MAS9999 Practical 1

  1. Write R code to plot the cars dataset.
  1. Find the numerical value of \(2\pi\), to 4 decimal places.
## [1] 6.2832
  1. Show that \(e^{i\pi}+1=0\).
    Solution: \[\begin{align*} e^{i\pi}+1&=\cos\pi+i\sin\pi+1\\ &=-1+i\times0+1=0 \end{align*}\]

2. Bookdown for lecture notes

R Markdown upgrade

A collection of .Rmd files

  • index.Rmd
  • 01-multivariate-data.Rmd
  • 02-pca.Rmd
  • 03-cluster.Rmd
  • 04-regression.Rmd
  • 05-regularisation.Rmd
  • 06-classification.Rmd
  • 07-matrix.Rmd
  • 08-factorisation.Rmd
  • 09-references.Rmd

 

{gaps, solutions} \(\times\) {.pdf, .html}

The parameter solution (again)

  • solution = FALSE: version with gaps
  • solution = TRUE: version with solutions
  • As before, make solutions to examples / exercises strings in R

 

The output format

  • bookdown::pdf_book: A single PDF with all chapters
  • bookdown::gitbook: Multiple HTML pages
  • Numbering of sections / figures / tables same across both formats
    • Needs a way that works for both

Labelling & referencing

Equations

  • (\#eq:euler) instead of \label{eq:euler}
  • \@ref(eq:euler) instead of \eqref(eq:euler)
    • The latter doesn’t exist
    • The prefix eq: suffices

 

The output

\[\begin{equation} e^{i\pi}+1=0\qquad\qquad\qquad (1) \end{equation}\] Equation (1) is the Euler’s identity.

Labelling & referencing

 

The output

Figure 1: Cars dataset.

Figure 1: Cars dataset.

A positive correlation between speed and dist can be seen in Figure 1.

Labelling & referencing

 

The output

Theorem 1 (Euler’s identity) \(e^{i\pi}+1=0\)

The proof of Theorem 1 is as below:

Proof. \[\begin{align*} e^{i\pi}+1&=\cos\pi+i\sin\pi+1\\ &=-1+i\times0+1=0 \end{align*}\]

Labelling & referencing

 

The output

Lemma 2 (Lemon)

Corollary 3 (Coriander)

Proposition 4 (Pepper)

Conjecture 5 (Confit)

Definition 6 (Daffodil)

Example 7 (Exotic)

Exercise 8 (Extract)

Hypothesis 9 (Hazelnut)

Lemma 2, Corollary 3, Proposition 4, Conjecture 5, Definition 6, Example 7, Exercise 8, Hypothesis 9

What about LaTeX environments & commands?

Some work

  • equation
  • align
  • aligned
  • eqnarray
  • array
  • (and their * versions)
  • $$ $$
  • \[ \]

 

Some don’t (for HTML)

  • center
  • tabular
  • displaymath
  • \intertext
  • \textcolor
  • \medskip
  • \bigskip
  • \hfill
  • \newpage

 

Some have been taken care of

  • enumerate: (R)markdown can do lists
  • itemize: (R)markdown can do lists
  • quote: (R)markdown can do quotes
  • solution: The hack using strings in R
  • verbatim: Backticks ``
  • example: Environment extended by bookdown
  • exercise: Environment extended by bookdown
  • figure

Canvas integration

3. Practical considerations

Converting existing materials

Cons

  • Fewer environments that work \(\qquad\qquad\quad\longrightarrow\)
    • And have to adapt to new environments
  • Have to check both formats back and forth \(\quad\longrightarrow\)
    • Experiment what works and what doesn’t
  • You don’t have fewer script files \(~\quad\qquad\quad\longrightarrow\)
    • Notes
    • Practicals
    • Slides
    • Assignments
  • Time cost & manual work \(~\qquad\quad\quad\qquad\longrightarrow\quad?\)

 

Pros

  • Scripts usually reproducible
    • Subject to package version changes
  • Checks the accessibility box once & for all
  • Separates content creation from formatting
  • A tidier set of files
    • .out, .log, .dvi, .blg, .bbl, .aux, .synctex.gz
    • figures/, .R, .RData

A list of tasks (in this order)

  1. Move \label{} outside (sub)(sub)section headings
  2. Replacements with regular expressions (regex)
  3. Replacements with strings
  4. Remove LaTeX commands: \textcolor, \medskip, \bigskip, \hfill, \newpage, \intertext
  5. Edit section & equation labels & \eqref{}
  6. Edit “other” environments in conjunction with their labels
  7. Edit itemize & enumerate environments
  8. Convert environments to R code chunks:
    • solution: the string hack
    • figure: knitr::include_graphics() (& convert .pdf to .png)
    • verbatim: actual R code without hardcoded results
    • tabular: knitr::kable() (or markdown syntax for tables)
  9. Fix code chunk labels ("_" \(\rightarrow\) “-”) & options: dev, out.width
  10. Add space in solution code chunks for PDF version, in conjunction with figure positions

Previously

 

Replacements (in this order)

Before After Remarks
\label{([^}]+)_([^}]+)_([^}]+)} {#\1-\2-\3} Similar for those with fewer "_"
\ref{([^}]+)_([^}]+)_([^}]+)} \@ref(\1-\2-\3) Ditto
\section{([^}]+)} ## \1 One # fewer for single document
\section*{([^}]+)} ## \1 {-} Ditto; similar for (sub)(sub)sections
\textit{([^}]+)} *\1* Same for \emph{([^}]+)}
\textbf{([^}]+)} **\1**
\texttt{([^}]+)} `\1` Same for \verb
\Sexpr{([^}]+)} `r \1`
\footnote{([^}]+)} ^[\1]
` `(.*)'' "\1" Before below replacments with `
^<<>>=$ ```{r}
^<<(.*)>>= ```{r, \1}
^@[\s]? ```
^%(.*) <!-- \1 --> After fixing environments commented out
(self-defined LaTeX commands) (Markdown replacements) (or just original LaTeX commands)
Figure~ Figure Not regex; with space at the end;
same for Chapter, Section, etc.
\_ _ Not regex; same for \$, \% and \&

Preach what you practise

Scaffolding

  • R(Studio)
  • For standalone documents via R Markdown:
    • R package rmarkdown (all lowercase)
  • For standalone documents via Quarto:
    • R package quarto
  • For lecture notes via bookdown
    • R packages rmarkdown & bookdown
  • The R packages required for your module
    • Most likely in the R script
  • LaTeX distribution & packages required for PDF outputs
    • Installation outside R, or
    • R package tinytex \(\rightarrow\) tinytex::install_tinytex()
    • tinytex::tlmgr_install()
  • For Python content
    • R package reticulate
    • Python (3)

 

YMMV

  • Even though they are meant for reproducibility
  • Quarto in active development, R Markdown more stable
  • Labelling & referencing that works in bookdown doesn’t automatically work in R Markdown

Summary

One R Markdown script to render them all

Bookdown notes

Conversion considerations

Some useful sites (that I’ve visited 400 times)