Quarto

Literate programming

Aurélien Ginolhac, DLSM

University of Luxembourg

Tuesday, the 4th of March, 2025

Learning objectives

You will learn to:

  • How to structure files and folders
  • Use relative paths and RStudio projects
  • Use the markdown syntax
  • Create Quarto documents
  • Render to the output format you want
  • Use RStudio interface to
    • Create your documents
    • Insert R code
    • Build your final document

Organize your files

Absolute paths are NOT portable

Relative paths are

RStudio projects

Create the practicals RStudio project

Typical flow of data

Source data ➡️

  • Experimental data
  • External data sets
  • Manually collected data and meta data

Intermediate ➡️

  • Derived data
  • Computation
  • Manual curation
  • Tidy data

Analysis ➡️

  • Exploratory analysis
  • Statistical models
  • Hypothesis testing

Manuscript ➡️

  • Can you reproduce your work?
    • All numbers
    • Summaries
    • Images

One workflow

  • No editing of data at any step
  • All code needed to reproduce from one ingestions to manuscript coded and repeatable

Literate programming is the practice of mixing code and descriptive writing in order to execute and explain a data analysis simultaneously in the same document.

William Landau Developer of {targets}


For a bioinformatician, pure programming is barely happening, we need reports/websites where content and formatting are disconnected

Even better to separate content and rendering, outsourced to continuous integration/development.

Rmarkdown

Predecessor of Quarto. Files are .Rmd.

Version 1 in 2016, the idea was to have text and code in one document, execute code and let the final markdown converted to different formats by pandoc.

Quarto

Extended Rmarkdown. Languages and IDE agnostic

Why use Quarto ?

  • Write detailed reports
  • Ensure reproducibility
  • Mix programming languages (passing along variables)
  • Export a single (.qmd) document to various formats (PDF, HTML…)
  • Keep track of your analyses
  • Comment/describe each step of your analysis
  • Quarto extensions
  • Text file that can (should) be managed by a version control system (like git)

Markdown

  • Lightweight markup language with a simple syntax

HTML

<!DOCTYPE html>
<html>
<body>

<h1>This is a heading</h1>

<p>This is some text in a <b>paragraph</b></p>

<h2>This is a second level heading</h2>

<ul>
<li><a href="http://exa.com"><code>site</code></a>
<li><img src="https://images.computerhistory.org/revonline/images/500004391-03-01.jpg?w=200">
</ul>
</body>
</html>

Markdown equivalent

# This is a heading

This is some text in a **paragraph**

## This is a second level heading

- [`site`](http://exa.com)
- ![Two Tux and Linus](https://images.computerhistory.org/revonline/images/500004391-03-01.jpg?w=200)

Two Tux and Linus

Common text formatting tags

Headers

  • 6 levels are defined using #, ##, ###
  • From BIG to small
  • http://example.com is auto-linked
  • [site](http://example.com)
  • ![](path/to/image.jpg)
  • ![desc](path/to/image.jpg) for alternative description

Text style

  • bold (**bold**)
  • italic (*italic*)
  • Also italic (_Also italic_)
  • R2 (R^2^)
  • CO2 (CO~2~)

Bullet points

Use hyphens or stars (- / *)

- first
- second
- third thing

Verbatim code (no computation)

Use the 140 language syntax pandoc knows

  • code with backticks (`code`)
  • Triple backticks are delimiting code blocks:
```
This is *verbatim* code
# Even headers are not interpreted
```

rendered as:

This is *verbatim* code
# Even headers are not interpreted

Specify language

``` markdown
This is *verbatim* code
# Even headers are not interpreted
```
This is *verbatim* code
# Even headers are not interpreted


``` r
vec <- c("a", "b")
vec[2]
```

rendered as:

vec <- c("a", "b")
vec[2]

Including code to execute

Computation

  • In a fresh and clean session
  • Chunks are evaluated
  • Sequentially from top to bottom

Example for knitr

  • Extracts chunks
  • Interpret/Run them
  • Formats results as markdown
  • Reinject in the document (MD)

Pandoc

  • Converts markdown to the desired document
    • PDF
    • HTML
    • Word
    • EPUB

Quarto document: Structure

YAML header

  • Document common variables:
    • title, date, author, …
  • Define format and its specific options
  • Use Tab for autocompletion

Free text in Markdown

  • Markdown syntax to write your descriptions, remarks
  • Literate programming

Code chunks to be interpreted

  • Outputs (tables/plots) are inserted below each
  • knitr for
  • jupyter for
  • QuartoNotebookRunner.jl package for julia
  • Native support for Observable

Qmd creation: step 1

Under File, pick Quarto Document

  • Optionally fill in some header variables
  • Choose the output format (can be changed later)

Render Quarto documents

  1. Save the file, Untitled.qmd* cannot be rendered
  2. Click the Render
  • A new session is created
  • Chunks are evaluated top -> bottom
  • Outputs are injected in the MD
  • Final MD is converted by pandoc to chosen format: pdf

Example:

---
title: "Cereviase"
format: pdf
---

Default output is HTML

code chunks

Insert a chunk

```{r}
#| label: readin-csv
#| code-line-numbers: false
#| eval: false

# regular comment, not a hash pipe
wine <- read_csv("wine.tsv")
```

Basic Markup

  • Delimited by triple backticks tags (```)
  • Engine evaluating the code in curly braces
  • Options in hash pipe: #|
    • Label of chunk (optional)
    • Show/hide code #| echo: true
    • Evaluate or not #| eval: true
    • Figure size (inches) #| fig-width: 9

Inline R code

Integrate small pieces of code

Use backticks (`) followed by the keyword {r}:

`{r} some code`

Example

1 + 1 = `{r} 1 + 1`

=> renders as 1 + 1 = 2 .

More useful:

swiss dataset:`{r} nrow(swiss)` rows

=> renders as swiss dataset: 47 rows.

Output examples 1/2

HTML

Word

Output examples 2/2

Typst

PDF (LaTex)

Basic tables

Created from scratch

Dataset   | # rows            | Description
----------|------------------:|-------------------
swiss     | `{r} nrow(swiss)` | Swiss  Indicators
datasaurus| 1846              | 13 datasets of same mean
Dataset # rows Description
swiss 47 Swiss Indicators
datasaurus 1842 13 dataset of same mean

Tables with knitr::kable()

as_tibble(swiss, rownames = "Province") |>
  select(Province:Agriculture) |>
  slice_head(n = 5) |>
  knitr::kable(caption = "Swiss Socioeconomic Indicators (1888)")
Swiss Socioeconomic Indicators (1888)
Province Fertility Agriculture
Courtelary 80.2 17.0
Delemont 83.1 45.1
Franches-Mnt 92.5 39.7
Moutier 85.8 36.5
Neuveville 76.9 43.5

Equations using \(\LaTeX\) syntax

How to add equations

  • Enclose in $ for in-line equations

  • $a^2+b^2=c^2$ renders as \(a^2+b^2=c^2\).

  • Double ($$) for separate equations.

$$G_{\mu v}=8 \pi G (T_{\mu v} + \rho _\Lambda \ g_{\mu v}) $$

renders as:

\[G_{\mu v}=8 \pi G (T_{\mu v} + \rho _\Lambda \ g_{\mu v})\]

Potential pitfalls

  • MathJax needs to load, unstable internet connections can intervene

Solution embed libraries (but larger file size):

format:
  html:
    self-contained-math: true

Before we stop

You learned to:

  • Use relative paths in RStudio projects
  • What is Quarto (qmd)
  • Basic syntax of Markdown
  • Separate content from rendering
  • render to different output formats

Acknowledgments 🙏 👏

  • Mine Cetinkaya-Rundel
  • Xie Yihuie
  • Alison Horst
  • Hadley Wickham
  • Christophe Dervieux
  • William Landau
  • Artwork by Allison Horst
  • Jenny Bryan


Thank you for your attention!