Reproducible reports and presentations with Quarto

Jadey Ryan // July 1, 2024
Salt Lake City R Users Group

Jadey Ryan

Reproducibility

  • Data and style updates are inevitable

  • Manual updates are time-consuming and error-prone

Reproducibility spectrum figure by Roger D. Peng (2011)

Manual updates ❌

Illustration of a non-reproducible workflow for creating reports and presentations, highlighting the inefficiencies and error-prone nature of the copy/paste process.

Updates with Quarto ✅

Illustration of a reproducible workflow for creating reports and presentations with R and Quarto, showcasing the streamlined and efficient process.

What is Quarto?

Publishing system that supports multiple languages & outputs

Artwork from “Hello, Quarto” keynote by Julia Lowndes and Mine Çetinkaya-Rundel, presented at RStudio::Conf(2022). Illustrated by Allison Horst.

A schematic representing rendering of Quarto documents from .qmd, to knitr or jupyter, to plain text markdown, then converted by pandoc into any number of output types including html, PDF, or Word document.

Create all kinds of outputs

Get inspired by the Quarto.org gallery and the Qmd Club website & blog showcase

Anatomy of a .qmd file

  1. YAML header (metadata and document options)

  2. Narrative (markdown)

  3. Code chunks (import, wrangle, visualize data)

1. YAML header

“Yet Another Markup Language” or “YAML Ain’t Markup Language”

1---
2title: Quarto demo
author: Jadey Ryan
date: 2024-07-01
format:
3  html:
    theme: flatly
    toc: true
---
1
Demarcated by three dashes (---) on the top and bottom
2
Document level metadata and options using key-value pairs in the format key: value
3
Add 2 spaces for each indentation level – YAML is very fussy!


See available options in the reference guides: HTML, PDF, MS Word, Revealjs, MS Powerpoint.

2. Narrative

Markdown syntax for:

  • Text with formatting: **bold**bold

  • Section headers: # Header 1, # Header 2

  • Hyperlinks: [google.com](https://google.com)google.com

  • Images: ![](image.png)

  • Inline code: `{r} Sys.Date()`2024-07-01

  • Inline math: `$E = mc^{2}$`\(E = mc^{2}\)


3. Code chunks (or cells or blocks)

Three ways to insert code chunks:

  1. Keyboard shortcut Cmd/Ctrl + Option/Alt + I.

  2. Insert Chunk button in RStudio Insert Chunk button in the editor toolbar.

  3. Manually type the chunk delimiters ```{r} and ```.

Two ways to run code chunks:

  1. Use the Run Current Chunk or Run All Chunks Above buttons.

    Code chunk in RStudio with the Run All Chunks Above and Run Current Chunk buttons highlighted and labelled.

  2. Run the current code chunk with Cmd/Ctrl + Shift + Enter.

💃🏻 Demo

1-html-demo.qmd

Primer on parameters

Like a custom function

File with the word '.qmd' inside and the word 'Function' above.

An arrow points from 'Input' with 'params$year' to the previous image with 'Function' and '.qmd' file.

In addition to the previous two images, arrows point to five reports with years 2019 through 2023 on them in a flow chart.

What makes a document “parameterized”?

  • YAML header with params key-value pairs

  • Use params to create different variations of a report from a single .qmd document

Important

Set params in YAML header

---
title: "Swiss Cats"             # Metadata
format:                         # Set format types
  html:
    toc: true                   # Set additional options
  docx: default                           
params:                         # Set default parameter key-value pairs
  fave_breed: "Snowshoe"                                
---
    
Report content goes here.       # Write narrative and code

Important

Your default params key-value pairs must be found in your dataset. Otherwise, code will error or output will be blank.

The variable name for params can be anything you choose. Often, it’s a column name in your dataset.

Access params

Run any line or chunk to add params to your environment.

params object is a list.

str(params)
List of 1
 $ fave_breed: chr "Snowshoe"


Access with $ notation.

params$fave_breed
[1] "Snowshoe"


For inline code in YAML or report content, enclose the expression in `r `.

My favorite cat breed is the **`r params$fave_breed`**.

My favorite cat breed is the Snowshoe.

Replace hard-coded values with params

Cmd/Ctrl + F to find where to replace hard-coded values with params.

Find and replace toolbar with "pet_type in the Search field highlighted by a purple box and "params$pet_type in the Replace field highlighted by a blue box. The .qmd file shows a filter statement with the "pet_type highlighted by RStudio as a match for the Find tool. This filter statement is highlighted by a purple box with an arrow pointing to a blue box that has the filter statement with the hard-coded "cats string replaced with "params$pet_type.

Replace hard-coded values with params

Use $ list notation in code for plot/table titles and labels, filtering, etc.


paste() syntax:

# ggplot2 code +
    labs(title = paste(params$fave_breed, "population"))


glue::glue() syntax:

# ggplot2 code +
    labs(title = glue::glue("{params$fave_breed} population"))


Use inline R code for markdown.

## My favorite breed: **`r params$fave_breed`**.

Three ways to render

  1. RStudio/Quarto integration:

    Quarto render button in RStudio Render button in RStudio or Cmd/Ctrl + Shift + K keyboard shortcut

  2. Quarto R package

    Console or R script
    quarto::quarto_render(
      input = here::here("template.qmd"),   # Input Quarto file
      execute_params = list(                # Named list of params
        pet_type = "cats",
        fave_breed = "Snowshoe"))
  3. Quarto CLI

    Terminal
    quarto render template.qmd -P pet_type:'cats' -P fave_breed:'Snowshoe'

Tip

Learn how to programmatically render all reports at once from my previous workshops on parameterized reporting.

💃🏻 Demo

2-params-demo.qmd

Multiple report formats from a single .qmd

Add formats & options to the YAML

---
format:
  html: 
    embed-resources: true   # Makes the report self-contained
  pdf: default              # If not using any additional format options,
  docx: default             # set value to `default`  
---

Render button dropdown

Report → presentation

Presentation formats & basics


  • Create a new section with a level 1 heading (#)

  • Create a new slide with a level 2 heading (##) or a horizontal rule (---)


  • Put speaker notes in a {.notes} div:

    ::: {.notes}
    Notes show in speaker view. 
    Press the S key to enter speaker view when presenting Revealjs slides.
    :::

Incremental number & bullet lists

  • Make all lists incremental by setting the option in the YAML:

    format:
      revealjs:
        incremental: true
  • Make some lists non-incremental by wrapping it in a div:

    ::: {.nonincremental}
    - I have 3 snowshoe cats:
      - Mai
      - Tai
      - Skye
    :::
  • Make some lists incremental by wrapping it in a div:

    ::: {.incremental}
    - Snowshoe
    - cats
    - are
    - so
    - cute!
    :::

Revealjs has the most options

YAML for these slides:

format:
  revealjs:
    footer: "[jadeyryan.quarto.pub/slc-rug-quarto/](https://jadeyryan.quarto.pub/slc-rug-quarto/)"
    logo: "images/jr-logo-quarto.webp"
    logo-alt: "Jadey Ryan's cat hex logo joined by a heart with the Quarto hex sticker."
    width: 1600
    height: 900
    theme: slides.scss
    highlight-style: a11y
    transition: fade
    incremental: true
    slide-number: true
revealjs-plugins:
  - pointer

See all the YAML options in the Revealjs reference guide.

Check out Revealjs plugins like Pointer.

and the coolest features

column output location & code line-highlighting:

```{r}
#| output-location: column
#| code-line-numbers: "|3|5|8|10"

library(ggplot2)

mtcars |> 
  ggplot(aes(x = disp, y = mpg)) +
  geom_point() +
  geom_smooth(method = "loess", formula = "y~x")
```

Explore more features in the Revealjs Quarto docs

YAML options for HTML reports & Revealjs presentations

format: 
  html: 
1    output-file: report.html
2    theme: solar
  revealjs:
    output-file: slides.html
    theme: moon
3embed-resources: true
1
Use output-file to specify file name. Otherwise, they overwrite each other (e.g., template.qmdtemplate.html).
2
Use similar themes for styling consistency across publications.
3
Use embed-resources: true to bundle all files into the output. Specify this option at the root level to apply to all formats.

💃🏻 Demo

3-html-revealjs-demo.qmd

Styling with HTML and CSS

HTML format uses Bootswatch themes

Choose from or customize one of 25 Bootswatch themes.


Set the theme in the YAML under the html key:

format:
  html:
    theme: solar


Customize a theme by including a custom .scss file under the theme key:

format:
  html:
    theme: [solar, theme.scss]


HTML theming Quarto docs

Revealjs has its own themes

Preview themes at revealjs.com/themes.


Set the theme in the YAML under the revealjs key:

format:
  revealjs:
    theme: moon


Customize a theme by including a custom .scss file under the theme key:

format:
  revealjs:
    theme: [moon, theme.scss]


Revealjs theming Quarto docs

SCSS files

SCSS files have the following form:

/*-- scss:defaults --*/
$h2-font-size:          1.6rem !default;
$headings-font-weight:  500 !default;
$body-color:            $gray-700 !default;

/*-- scss:rules --*/
h1, h2, h3, h4, h5, h6 {
  text-shadow: -1px -1px 0 rgba(0, 0, 0, .3);
}


Define SASS variables in the defaults section.

Declare CSS rules in the rules section.


Bootstrap docs

Default Bootstrap variables

Emil Hvitfeldt’s Slidecraft 101 Series

Browser developer tools

Cmd/Ctrl + Shift + C in Google Chrome or Microsoft Edge then hover over the element to inspect.

Modify the CSS and copy/paste into your .scss file.

Screenshot of browser developer tools inspecting the Quarto title meta heading of an HTML report.

Screenshot of browser developer tools with the CSS declaration modified to test style changes.

Styling in Microsoft Office

Reference document

Create and modify a reference document, which is a special kind of template for .docx or .pptx.

  1. Run the following in the Terminal to create the reference doc:

    Terminal
    quarto pandoc -o template.docx --print-default-data-file reference.docx
  2. Open template.docx and modify the styles.

  3. Set this template in the YAML under the reference-doc: key:

    format:
      docx:
        reference-doc: template.docx

MS Word template Quarto docs

  1. Run the following in the Terminal to create the reference doc:

    Terminal
    quarto pandoc -o template.pptx --print-default-data-file reference.pptx
  2. Open template.pptx and modify the styles.

  3. Set this template in the YAML under the reference-doc: key:

    format:
      pptx:
        reference-doc: template.pptx

MS Powerpoint template Quarto docs

MS documentation on modifying styles

Wrap-up

More advanced features

Best practices

  • KISS principle: keep it super simple

  • Keep text minimal if rendering a report & presentation from the same .qmd, or use conditional content

  • Careful with features that only work in certain formats (e.g., interactivity)

  • Pick similar themes and use custom .scss files and reference documents to ensure consistent styling across all your documents

  • Use the Quarto docs as a reference & take advantage of the search feature

Next steps

  • Work through these slides and code snippets to try out these features

  • Check out the linked references

  • Be curious & explore the source code of reports & presentations you like

  • Have fun creating amazing things!

Caution

Quarto is an extremely powerful tool with many, many features and capabilities. It’s easy to get overwhelmed. Learn what you need and bookmark other things you’d like to learn later.

Thank you!

🏡 Home for slides:

jadeyryan.quarto.pub/slc-rug-quarto/

👩🏻‍💻 Source code:

github.com/jadeynryan/slc-rug-quarto

🎥 Recordings from previous workshops & talks:
links in GitHub repo or my YouTube playlist

From left to right, Mai, Tai, and Skye. Three snowshoe cats cuddling in their warming beds.