Who am I?

Data visualisation specialist, mainly working with R, Python, and D3.js.


Background in statistics, operational research, and data science consultancy.


Co-author of Royal Statistical Society’s Best Practices for Data Visualisation guidance.


Hex logos

What to expect during this workshop


  • Combines slides, live coding examples, and exercises for you to participate in.

  • Ask questions throughout!


Stranger Things questions gif

Source: giphy.com

Workshop resources

Course website: nrennie.rbind.io/r-medicine-2026-parameterized-reports

Screenshot of course website

What do I mean by parameterized plots?

A plot where aspects of the visualisation are controlled by one or more parameters.

  • Time period
  • Geographic region
  • Assumptions about data

Controls the underlying data, captions, title, colours, ….

Gif of Scrollytelling piece with different versions of a plot

Why parameterize plots?

Essentially so that you Don’t Repeat Yourself:

  • Once you’ve parameterized a plot, it’s quick to make different versions of the same plot.

  • Scripts are shorter and easier to read because you’re not copying and pasting code.

  • Ensure consistent layout between plots.

Start with variables…

Create variables that define the data you’re plotting:

month <- "Apr"
year <- 2024

Variables don’t have to be data-related, they can also be:

  • colours
  • fonts
  • output types

…then build functions!

plot_function <- function(month, year) {
  # plot code goes here!
}


with or without default…

plot_function <- function(month, year, colour = "blue") {
  # plot code goes here!
}

Live Demo!

  • Replacing hard-coded values with variables

  • Transforming code into a function

  • Using glue() for parameterized plot text

Exercise 1

  1. Create a variable to define a year in the gapminder data that you want to plot.

  2. Edit the code in the gapminder_year.R file to use this new year variable.

  3. Turn your code into a function that takes the data and year variable as arguments (and check it works!)

  4. Bonus: Add another argument to your function that allows a user to define the bar colour.

  5. Bonus: How could you improve your function?

What is Quarto?

Quarto is an open-source scientific and technical publishing system that allows you to combine text, images, code, plots, and tables in a fully-reproducible document. Quarto has support for multiple languages including R, Python, Julia, and Observable. It also works for a range of output formats such as PDFs, HTML documents, websites, presentations,…

Quarto logo

What makes a Quarto document?

YAML header

---
title: "A very cool title"
format: html
---


Content

  • Text, links, images

  • Code, tables, plots

  • Equations, references

Output types

  • Documents: HTML, PDF, MS Word, Markdown

  • Presentations: Revealjs, PowerPoint, Beamer

  • Websites

  • Books

Quarto parameters

---
title: "A very cool title"
format: html
params:
  year: 2023
---


Note: you can do something similar with R Markdown.

Using parameters in code

Subset data based on parameters:

data_subset <- data |>
  dplyr::filter(
    year == params$year
  )

Parameters with Python code

```{python}
#| tags: [parameters]

alpha = 0.1
ratio = 0.1
```

Using in code:

```{python}
alpha
```

Live Demo!

  • Adding a continent parameter to the document

  • Accessing and using the parameter in plotting

  • Using the parameter for tables

Exercise 2

  1. Edit the report.qmd file to add a parameter for year.

  2. Add your plotting function to the quarto document, and pass the parameter into the plotting function. Check it renders.

  3. Change the value of the parameter, and re-render.

Inline text

Sometimes you want to use values from code in a sentence. We can add inline code:

The number of rows is `r nrow(gapminder)`.


which displays as:

The number of rows is 1704.

Captions

You can also execute R code in figure captions:

```{r}
#| label: fig-gapminder
#| fig-cap: !expr 'paste("The number of rows is ", nrow(gapminder))'
#| output-location: column-fragment
#| eval: true
hist(gapminder$lifeExp)
```
Figure 1: The number of rows is 1704

Live Demo!

  • Writing inline R code

  • Using parameter values in inline R code

  • Using parameter values in figure captions

Exercise 3

  1. Edit the sentence ...a plot of the median life expectancy in the year 1952 for each continent... to use inline code to add the document parameter for the year.

  2. Use inline code for the title as well.

  3. Edit the figure caption to use inline code to add the document parameter for the year.

Rendering multiple reports

Let’s say you want to create multiple different versions of your report.

  • Manually change parameter values and hit render?

  • Pass parameters in one at a time to the command line?

Using the {quarto} R package

The {quarto} R package provides an interface to the Quarto CLI.


We can use the quarto_render() function as an alternative to the Render button or command line.


Then a for loop?

Quarto logo

Using the {purrr} package

  • Replace for loops with code that is shorter and easier to read.

  • Map over a vector of different e.g. continents, time periods, …

  • Use the walk() functions from {purrr} to call a function for it’s side effect e.g. rendering a report.

purrr logo

Note: if you’re more a base R person, you can do something similar with the apply() family of functions.

Live Demo!

  • Using the {quarto} R package.

  • Using {purrr} to generate multiple reports.

Exercise 4

  1. Render a version of your report for the year 1972 using the quarto_render() function.

  2. Render a version of your report for all years in the data.

Conditional on output format

Display content only for a specific format:

::: {.content-visible when-format="html"}

Will only appear in HTML.

:::


::: {.content-hidden unless-format="pdf"}

Will be hidden unless it's a PDF document.

:::

Conditional on parameters (or data values)

Display content only for a specific parameter value:

`r if (params$hide_answers) "::: {.content-hidden}"`

The answer is 4.

`r if (params$hide_answers) ":::"`

Quarto profiles

  • Main project configuration: _quarto.yml

  • solutions profile configuration: _quarto-solutions.yml

::: {.content-hidden when-profile="solutions"}

This content will be hidden in the advanced profile

:::

Live Demo!

  • Interactive vs static charts in HTML vs PDF

  • Showing content based on parameters

Exercise 5

  • Edit the .qmd file from Exercise 3. When the format is HTML show an interactive chart using plotly, otherwise show a static chart.

  • When the year parameter is 2007, add a sentence to state that it is the most recent data available.

  • Bonus: Can you edit the logic you applied to check programmatically if it’s the last year in the data?

Ways to re-use content

You can use the following features to re-use content, either across documents or within different sections of a document.

  • file
  • include
  • knit_child()

#| file:

  • Source a .R file within your Quarto script #| file: ../R/utils.R
  • Good way to separate out long (reusable) pieces of code e.g. functions
  • Nice way to load set up code across each document e.g. themes

include

  • Built-in Quarto shortcode {{< include _content.qmd >}}
  • Equivalent to copying and pasting the text from the included file into the main file
  • Need to be careful with e.g. image paths in included document
  • You can also include .R files (but don’t have code block options in the same way)
  • Use an underscore (_) prefix for the included file names means Quarto ignores them properly.

Child documents

  • Similar to include i.e. taking one .qmd file and placing its contents inside another
  • Add documents with the knit_child() function
  • Since it’s an R function, we can loop over parameters

Warning

  • This is a knitr feature, not a Quarto feature
  • Doesn’t always trigger auto-re-rendering when the child file changes

Live Demo!

  • Loading R scripts
  • Working with includes
  • Knitting child documents

Exercise 6

  • Separate out the barchart_year() function into a separate R script.
  • Load it in using file: instead.
  • Create a child file containing the year as a section heading, followed by the chart.
  • Render document with a section for each year in the data.

Workshop resources

Workshop website: nrennie.rbind.io/r-medicine-2026-parameterized-reports

Screenshot of course website