Technical Writing

Technical writing and literate programming in Quarto documents.
Author

Michael McCarthy

Published

January 24, 2023

Literate programming

Literate programming is the practice of mixing text and executable code in the same document, making it possible to write reproducible documents. There are four engines for executing code in Quarto documents:

All engines support executing code in code blocks within a document, which can be used to execute code and include its output in a document. Code blocks can produce a wide variety of outputs, including plots, tabular output from data frames, and plain text. The behaviour of code execution and output can be set with Quarto’s Execution Options.

knitr, jupyter, and Observable JS also support executing inline code within markdown text, which can be used to allow narrative to automatically use the most up to date computations. The syntax for inline code varies across the engines.

The remainder of this post covers some useful literate programming practices when writing reproducible documents with the knitr engine.

Project management

Literate programming is a powerful tool for writing reproducible documents, but it can also become unwieldy if your computations require a lot of code. Rather than writing all the code within a document, it is often better to source the required code within a document, then include output using the objects created by the sourced code. The simplest way to adopt this approach is by using the source() function to source R script files containing the computations for a document; a better way is to use the literate programming approach described in the targets R package.

Plain text outputs

Most code you write will be output as plain text. Depending on the purpose of a document, it might be fine to leave that output as is, or you might want to format the text, include it inline, and so forth.

For example, say you wanted to report the number of participants in a study you ran. Rather than writing a sentence like this:

There were twelve participants in the study.

You could get the number of participants computationally, format that number into the word “twelve”, and include it in the sentence using inline code:

n_participants <- xfun::numbers_to_words(12)

There were `r n_participants` participants in the study.

This sentence would become “There were twelve participants in the study.” when you render the document. Likewise, if the number of participants changed, the number reported in the sentence would change the next time the document rendered (as long as the R object storing the number of participants knew about the change).

If there are many values you need to report inline, storing them in a list is a good practice. For an overview of this approach, see:

Figure and table outputs

Figures and tables produced by code blocks have unique parameters you can use to adjust their layout, add captions, or make them cross-referenceable. See the Quarto documentation for details:

Adjusting figure appearance

When making figures with ggplot2 it’s best to know the final size of the figure before attempting to adjust the size of plot text or geometry.

Equations

Quarto features extensive support for writing beautiful math equations with LaTeX math expressions authored using standard Pandoc markdown syntax: Use $ delimiters for inline math and $$ delimiters for display math. Provide an #eq- label immediately after a display math equation to make it referenceable.

Markdown Syntax Output
inline math: $E = mc^{2}$ inline math: E=mc^{2}

display math:

$$E = mc^{2}$$

display math:
E = mc^{2}

display math with label:

$$E = mc^{2}$${#eq-mc-squared}

display math with label:
E = mc^{2} \tag{1}

Math expressions can be rendered in any of Quarto’s output formats, but different rendering methods are used depending on the format:

To learn more about writing LaTeX math expressions, see:

Inspecting equations rendered by MathJax

Equations rendered by MathJax can be inspected by right clicking them. This is useful if you want to view or copy the underlying TeX code from an equation Show Math As > TeX Commands or Copy to Clipboard > TeX Commands. Note that Tidy Tales uses the KaTeX renderer, so it won’t work on this site.

Using inline R code in math equations

Inline R code `r ` can be used within inline or display math to include code output in math equations.

mtcars_fit <- lm(mpg ~ am, data = mtcars)
coef_int   <- coef(mtcars_fit)["(Intercept)"]
coef_am    <- coef(mtcars_fit)["am"]

Inline math: $\mathrm{\widehat{mpg}} = `r coef_int` + `r coef_am`(\mathrm{am})$

Inline math: \mathrm{\widehat{mpg}} = 17.1473684 + 7.2449393(\mathrm{am})

The same approach also works for display math.

Writing model equations

The equatiomatic package can be used to write equations from a fitted model. Learn more on the package website.

library(equatiomatic)

By default the model equation uses math symbols.

extract_eq(mtcars_fit)
#> $$
#> \operatorname{mpg} = \alpha + \beta_{1}(\operatorname{am}) + \epsilon
#> $$

But model estimates can be used too.

extract_eq(mtcars_fit, use_coefs = TRUE)
#> $$
#> \operatorname{\widehat{mpg}} = 17.15 + 7.24(\operatorname{am})
#> $$

Using math equations in plots

Both base R and ggplot2 plots feature support for writing beautiful math equations with plotmath expressions. Equations can be used in plot labels, legends, and text.

If you would rather write equations using LaTeX math expressions, the latex2exp package can be used to parse and convert LaTeX to plotmath expressions.2 Learn more on the package website.

ggplot2 also includes some convenience functions for using plotmath in plot labels:

  • label_parsed() interprets labels as plotmath expressions
  • label_bquote() offers a flexible way of labelling facet rows or columns with plotmath expressions

Footnotes

  1. MathJax is an open-source JavaScript rendering engine for LaTeX math expressions. It is the default rendering method in Quarto HTML documents.↩︎

  2. There is also an open issue to support LaTeX math expressions using markdown in the ggtext package.↩︎