R/Medicine Data Cleaning 2023 Workshop taught by Crystal Lewis, Shannon Pileggi, and Peter Higgins
ASA Traveling Courses on Quarto taught by Mine Çetinkaya-Rundel and Andrew Bray
Opinions expressed are solely my own and do not express the views of my employer or any organizations I am associated with.
This work is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA).
Data scientist at WA Dept of Agriculture
Business owner of The Coding Cats
Photo credit: @leslie.mmichel
Login to Posit Cloud: bit.ly/rladies-parameterized-quarto.
If Posit Cloud doesn’t work, download materials locally:
Ask questions in the public Zoom chat or raise hand ✋.
Workshop structure: presentation, exercises, questions to answer in chat [💬 Chat:], and demos.
Raise/lower your hand on Zoom.
Use your favorite reaction.
💬 Chat: share your name, where you’re calling from, and one thing you’ve made that you’re proud of.
01:00
2014+ magrittr pipe %>%
2021+ (R \(\geq\) 4.1.0) native R pipe |>
Isabella Velásquez’s blog post Understanding the native R pipe |> (2022)
To change Ctrl
+ Shift
+ M
shortcut to the native pipe:
Tools
→ Global Options
→ Code
→ Editing
→ Use Native Pipe Operator
Slide adapted from R/Medicine Data Cleaning 2023 Workshop
package::function()
dplyr::select()
tells R explicitly to use the function select
from the package dplyr
helps avoid name conflicts (e.g., MASS::select()
)
does not require library(dplyr)
Slide adapted from R/Medicine Data Cleaning 2023 Workshop
Tools
→ Global Options
→
Fussy YAML indentation:
Code
→ Display
→ Indentation guides:
→ Rainbow lines
Match parentheses:
Code
→ Display
→ Indentation guides:
→ Check Use rainbow parentheses
Matching divs:
R Markdown
→ Advanced
→ Check Use rainbow fenced divs
💬 Chat: what’s your comfort level / experience with R Markdown and Quarto?
Vast R Markdown ecosystem
Dependent on R
Command line interface (CLI)
Expands R Markdown ecosystem
“Batteries included”
Multi-language and multi-engine
R Markdown will still be maintained but likely no new features (Xie 2022).
No Quarto equivalent to .Rmd Knit with Parameters GUI built with Shiny {miniUI}.
Workaround: build webapp to get input, serialize to YAML, pass to Quarto render.
More info: GitHub discussion
.Rmd
→ .qmd
*.Rmd
→ .qmd
output:
→ format:
)knitr::convert_chunk_header()
*If you want.
From R Markdown to Quarto workshop taught by Dr. Mine Çetinkaya-Rundel and Dr. Andrew Bray.
Ted Laderas’ talk Quarto/RMarkdown - What’s Different?
Different audiences, different reports
Show code for technical staff and hide code for everyone else.
See this StackOverflow question and answer for an example.
💬 Chat: what kinds of reports would you like to parameterize? What would the parameters be?
YAML header with params
key-value pairs
Use those params
in your report to create different variations
Important
Valid parameter values are strings, numbers, or Boolean.
Must serialize a dataframe to pass it as a parameter, then un-serialize it back to a dataframe within the .qmd
content.
See Christophe Dervieux’s answer in Posit Community to understand why.
See John Paul Helveston’s blog post to learn how to use {jsonlite} as a workaround.
Write report template with default values hard-coded, and then render & review.
Set default params
key-value pairs in YAML. Replace hard-coded values with the params
variables.
Render the single report and review.
Render extreme cases and review.
Render all variations of the report at once.
Explore a report without parameters and see where we could add them.
Open ex-1-swiss-cats.qmd
.
Click the Render button.
Look at the source markdown and code and the rendered report.
Update your name as the author. Re-render.
💬 Chat: what variables could we set as parameters?
05:00
params
in YAML headerImportant
Your default params
key-value pairs must be found in your dataset.
params
Run any line or chunk to add params
to your environment.
params
Ctrl
+ F
to find where to replace hard-coded values with params
Modify ex-1-swiss-cats.qmd
to add pet_type
and fave_breed
parameters.
Render button in RStudio or Ctrl
+ Shift
+ K
keyboard shortcut
Check Render on Save
and Ctrl
+ S
keyboard shortcut
Quarto CLI
✨ quarto::quarto_render()
Change parameters and render using 1) Render button and 2) quarto_render()
.
Look at the unique pet breeds and pick your favorite.
In ex-2-quarto-render.qmd
Change the default parameters in the YAML to your favorite pet type and breed. Render using the button.
Now render with quarto::quarto_render()
. Replace ___
with different parameters:
💬 Chat: what’s your fave breed and do you have any pets? 🐈🐕🐹🐍🐠
07:00
One HTML report for each cat breed and each dog breed.
Change the default params
in the YAML.
Render button in RStudio or Ctrl
+ Shift
+ K
keyboard shortcut.
Change the file name to add the parameter.
output-file:
YAML option doesn’t seem to work with inline R code.
Repeat 537 times.
quarto::quarto_render(
input = here::here("ex-2-quarto-render.qmd"),
output_file = "dogs-affenpinscher-report.html",
execute_params = list(
pet_type = "dogs",
fave_breed = "Affenpinscher"))
quarto::quarto_render(
input = here::here("ex-2-quarto-render.qmd"),
output_file = "dogs-afghan-hound-report.html",
execute_params = list(
pet_type = "dogs",
fave_breed = "Afghan Hound"))
quarto::quarto_render(
input = here::here("ex-2-quarto-render.qmd"),
output_file = "dogs-aidi-chien-de-montagne-de-l-atlas-report.html",
execute_params = list(
pet_type = "dogs",
fave_breed = "Aidi Chien De Montagne De L Atlas"))
quarto::quarto_render(
input = here::here("ex-2-quarto-render.qmd"),
output_file = "dogs-akita-report.html",
execute_params = list(
pet_type = "dogs",
fave_breed = "Akita"))
# + 534 more times...
Create a dataframe with three columns that match quarto_render()
args:
output_format
: file type (html, revealjs, pdf, docx, etc.)
output_file
: file name with extension
execute_params
: named list of parameters
Map over each row:
purrr::pwalk(dataframe, quarto_render, quarto_render_args)
pet_reports <- pets |>
dplyr::distinct(pet_type, breed) |> # Get distinct pet/breed combos
dplyr::mutate(
output_format = "html", # Make output_format column
output_file = paste( # Make output_file column
tolower(pet_type),
tolower(gsub(" ", "-", breed)),
"report.html",
sep = "-"
),
execute_params = purrr::map2( # Make execute_params column
pet_type,
breed,
\(pet_type, breed) list(pet_type = pet_type, breed = breed)))
pet_reports_subset <- pet_reports |>
dplyr::slice_head(n = 2, by = pet_type) |>
dplyr::select(output_file, execute_params)
pet_reports_subset
output_file | execute_params |
---|---|
cats-abyssiniane-report.html | cats , Abyssiniane |
cats-aegean-cat-report.html | cats , Aegean Cat |
dogs-affenpinscher-report.html | dogs , Affenpinscher |
dogs-afghan-hound-report.html | dogs , Afghan Hound |
purrr::pwalk()
iterates over multiple arguments simultaneously.
First .l
argument is a list of vectors.
.l
that iterates over rows.Can’t render reports to another directory.
output-dir
YAML option only works for Quarto projects that have _quarto.yml
.
Workaround: use {fs}
to move files after rendering. See ex-3-render-reports.R
for example.
More info: GitHub discussion and GitHub issue.
If using embed-resources: true
YAML option, .qmd
can’t be in subfolder, otherwise:
[WARNING] Could not fetch resource …
More info: GitHub discussion and GitHub issue.
Demo ex-3-render-reports.R
.
Add to the format:
YAML option to render additional output formats from the same .qmd
file.
---
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`
---
Note: the Render button now has a dropdown!
Links to download the other formats will automatically appear in HTML documents.
Choose which format links to include:
Add another format by updating 1) the YAML, 2) the pet_reports
dataframe, and 3) the regexp
argument.
Modify the YAML of ex-3-render-reports.qmd
to add a new format (see all the options).
Modify ex-3-render-reports.R
to:
Add this new format to the pet_reports
dataframe used in pwalk()
Include “.html” OR “.docx” OR “.pdf” in the regexp
argument in dir_ls()
Hint: use the |
pipe OR
operator.
💬 Chat: were any of these functions from the .qmd
or .R
files new to you?
10:00
Special .content-visible
and .content-hidden
classes with when-format="___"
and unless-format="___"
attributes can be applied to:
Examples from Conditional Content Quarto docs
Pairs well with {{< include >}}
shortcodes to re-use content without copying/pasting.
Use an underscore (_) prefix for included files so they are automatically ignored by a Quarto render of a project (Includes Quarto Docs).
Use .content-visible unless-format="html"
Use conditional content divs to control when tabsets are shown.
ex-4-conditional-content.qmd
so that the panel-tabset
visible for .html reports and hidden for .pdf & .docx reports.Options:
{.content-visible when-format=“___“}
{.content-visible unless-format=“___“}
{.content-hidden unless-format=“___“}
{.content-hidden unless-format=“___“}
05:00
More efficient to not execute code that generates interactive outputs for static reports.
Useful for executing interactive plot code for HTML reports and static ggplot2
code for all other formats.
Not currently a feature of Quarto v1.3, but a Quarto dev thinks it could be possible in v1.4 according to this GitHub discussion. Granted, that comment was from 2023-01-02…
Include in the setup chunk of your .qmd
file.
Get the format of the Pandoc output:
eval: !expr
chunk optionSet a format
variable and use it in the eval:
chunk option to execute ggplot2
code only for static reports and plotly
code only for HTML documents.
ex-5-conditional-code.qmd
, get the output format in a variable in the setup
chunk.ggplot
code blocks and plotly
code blocks.05:00
Understand what parameterized reporting is and when it is useful.
Like very fancy custom functions:
Function → .qmd
template
Input → parameters
Output → rendered reports
Useful for creating variations of the same report:
country, state, county, or city
time periods
breeds, species, diseases, trials, etc.
Note
We only covered reports, but you can also parameterize revealjs
presentations! See this Jumping Rivers blog post about it.
Learn how to convert a report into a parameterized template.
Render all variations of the report at once using {quarto} and {purrr}.
Generate multiple format outputs from the same template with conditional content and code.
{.content-visible when-format=“___“}
{.content-visible unless-format=“___“}
{.content-hidden unless-format=“___“}
{.content-hidden unless-format=“___“}
🙏🏼 Please let me know how I did in this short survey
🏡 Home for all workshop materials: https://jadeyryan.quarto.pub/rladies-dc-quarto-params/
Parameterized Reporting with Quarto // jadeyryan.quarto.pub/rladies-dc-quarto-params/