Documents

From R Markdown to Quarto

Andrew Bray

UC Berkeley

Mine Çetinkaya Rundel

Duke University + Posit

Where does the name “Quarto” come from?

Anatomy of a Quarto document

Components

  1. Metadata: YAML

  2. Text: Markdown

  3. Code: Executed via knitr or jupyter

Weave it all together, and you have beautiful, powerful, and useful outputs!

Literate programming

Literate programming is writing out the program logic in a human language with included code snippets (separated by a primitive markup) and macros.

---
title: "ggplot2 demo"
date: "5/19/2023"
format: html
---

## MPG

There is a relationship between city and highway mileage.

```{r}
#| label: fig-mpg

library(ggplot2)

ggplot(mpg, aes(x = cty, y = hwy)) + 
  geom_point() + 
  geom_smooth(method = "loess")
```

Metadata

YAML

“Yet Another Markup Language” or “YAML Ain’t Markup Language” is used to provide document level metadata …

… in key-value pairs,

… that can nest,

… are fussy about indentation,

… and are kept between ---.

---
key: value
---

Example: Output options

---
format: something
---


---
format: html
---
---
format: pdf
---
---
format: revealjs
---

Example: Indented nesting

Indentation matters!

---
format: 
  html:
    toc: true
    code-fold: true
---

Fussing with YAML (invalid)

  • Invalid: No space after :
---
format:html
---
  • Invalid: Read as missing
---
format:
html
---
  • Valid, but needs next object
---
format: 
  html:
---

Fussing with YAML (valid)

There are multiple ways of formatting valid YAML:

  • Valid: There’s a space after :
format: html
  • Valid: There are 2 spaces a new line and no trailing :
format:
  html
  • Valid: format: html with additional options made with proper indentation
format: 
  html:
    toc: true

Why YAML?

To avoid manually typing out all the options, every time when rendering via the CLI:

quarto render document.qmd --to html


quarto render document.qmd --to html -M code-fold:true


quarto render document.qmd --to html -M code-fold:true -P alpha:0.2 -P ratio:0.3

Quarto linting

Lint, or a linter, is a static code analysis tool used to flag programming errors, bugs, stylistic errors and suspicious constructs.


Quarto YAML Intelligence

RStudio + VSCode provide rich tab-completion - start a word and tab to complete, or Ctrl + space to see all available options.


Your turn

  • Open hello-penguins.qmd in RStudio.
  • Try Ctrl + space to see the available YAML options.
  • Try out the tab-completion of any options that sound interesting.
  • Bring back your two favorite to share in chat when we return from breakout rooms.
  • You can use the HTML reference as needed.
05:00

List of valid YAML fields

Text

Text Formatting

Markdown Syntax Output
*italics* and **bold**
italics and bold
superscript^2^ / subscript~2~
superscript2 / subscript2
~~strikethrough~~
strikethrough
`verbatim code`
verbatim code

Headings

Markdown Syntax Output
# Header 1

Header 1

## Header 2

Header 2

### Header 3

Header 3

#### Header 4

Header 4

##### Header 5
Header 5
###### Header 6
Header 6

Markdown figures

![Penguins playing with a Quarto ball](images/penguins-quarto-ball.png)

Penguins playing with a Quarto ball

Markdown figures with options

![](images/penguins-quarto-ball.png){fig-align="left" width=250}

![](images/penguins-quarto-ball.png){fig-align="right" width=250 fig-alt="Illustration of two penguins playing with a Quarto ball."}

Illustration of two penguins playing with a Quarto ball.

Lists

Unordered list:

Markdown:

-   unordered list         
    -   sub-item 1         
    -   sub-item 1         
        -   sub-sub-item 1 

Output

  • unordered list
    • sub-item 1
    • sub-item 1
      • sub-sub-item 1

Ordered list:

Markdown:

1. ordered list            
2. item 2                  
   i. sub-item 1          
      A.  sub-sub-item 1

Output

  1. ordered list
  2. item 2
    1. sub-item 1
      1. sub-sub-item 1

Quotes

Markdown:

> Let us change our traditional attitude to the construction of programs: Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do. 
> - Donald Knuth, Literate Programming

Output:

Let us change our traditional attitude to the construction of programs: Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do. - Donald Knuth, Literate Programming

Your turn

  • Open markdown-syntax.qmd in RStudio.
  • Follow the instructions in the document for how to modify it.
  • When we get back from breakout rooms, please share one thing you learned in chat.
05:00

Tables

Markdown tables

Markdown:

| Right | Left | Default | Center |
|------:|:-----|---------|:------:|
|   12  |  12  |    12   |    12  |
|  123  |  123 |   123   |   123  |
|    1  |    1 |     1   |     1  |

Output:

Right Left Default Center
12 12 12 12
123 123 123 123
1 1 1 1

Grid tables

Markdown:

+---------------+---------------+--------------------+
| Fruit         | Price         | Advantages         |
+===============+===============+====================+
| Bananas       | $1.34         | - built-in wrapper |
|               |               | - bright color     |
+---------------+---------------+--------------------+
| Oranges       | $2.10         | - cures scurvy     |
|               |               | - tasty            |
+---------------+---------------+--------------------+

: Sample grid table.

Grid tables

Output:

Sample grid table.
Fruit Price Advantages
Bananas $1.34
  • built-in wrapper
  • bright color
Oranges $2.10
  • cures scurvy
  • tasty

Grid tables: Alignment

  • Alignments can be specified as with pipe tables, by putting colons at the boundaries of the separator line after the header:
+---------------+---------------+--------------------+
| Right         | Left          | Centered           |
+==============:+:==============+:==================:+
| Bananas       | $1.34         | built-in wrapper   |
+---------------+---------------+--------------------+
  • For headerless tables, the colons go on the top line instead:
+--------------:+:--------------+:------------------:+
| Right         | Left          | Centered           |
+---------------+---------------+--------------------+

Grid tables: Authoring

  • Note that grid tables are quite awkward to write with a plain text editor because unlike pipe tables, the column indicators must align.

  • The Visual Editor can assist in making these tables!

Tables from code

The knitr package can turn data frames into tables with knitr::kable():

library(knitr)
library(palmerpenguins)

head(penguins) |> 
  kable()
species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex year
Adelie Torgersen 39.1 18.7 181 3750 male 2007
Adelie Torgersen 39.5 17.4 186 3800 female 2007
Adelie Torgersen 40.3 18.0 195 3250 female 2007
Adelie Torgersen NA NA NA NA NA 2007
Adelie Torgersen 36.7 19.3 193 3450 female 2007
Adelie Torgersen 39.3 20.6 190 3650 male 2007

Tables from code

If you want fancier tables, try the gt package and all that it offers!

library(gt)

head(penguins) |> 
  gt() |>
  tab_style(
    style = list(
      cell_fill(color = "pink"),
      cell_text(style = "italic")
      ),
    locations = cells_body(
      columns = bill_length_mm,
      rows = bill_length_mm > 40
    )
  )
species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex year
Adelie Torgersen 39.1 18.7 181 3750 male 2007
Adelie Torgersen 39.5 17.4 186 3800 female 2007
Adelie Torgersen 40.3 18.0 195 3250 female 2007
Adelie Torgersen NA NA NA NA NA 2007
Adelie Torgersen 36.7 19.3 193 3450 female 2007
Adelie Torgersen 39.3 20.6 190 3650 male 2007

Cross references

Cross references

  • Help readers to navigate your document with numbered references and hyperlinks to entities like figures and tables.

  • Cross referencing steps:

    • Add a caption to your figure or table.
    • Give an id to your figure or table, starting with fig- or tbl-.
    • Refer to it with @fig-... or @tbl-....

Figure cross references

The presence of the caption (Blue penguin) and label (#fig-blue-penguin) make this figure referenceable:

Markdown:

See @fig-blue-penguin for a cute blue penguin.
![Blue penguin](images/blue-penguin.png){#fig-blue-penguin}

Output:

See Figure 1 for a cute blue penguin.

A blue penguin

Figure 1: Blue Penguin

Table cross references (from code)

The presence of the caption (A few penguins) and label (#tbl-penguins) make this table referenceable:

Markdown:

See @tbl-penguins for data on a few penguins.

```{r}
#| label: tbl-penguins
#| tbl-cap: A few penguins

head(penguins) |> 
  gt()
```

Output:

See Table 1 for data on a few penguins.

head(penguins) |> 
  gt()
Table 1:

A few penguins

species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex year
Adelie Torgersen 39.1 18.7 181 3750 male 2007
Adelie Torgersen 39.5 17.4 186 3800 female 2007
Adelie Torgersen 40.3 18.0 195 3250 female 2007
Adelie Torgersen NA NA NA NA NA 2007
Adelie Torgersen 36.7 19.3 193 3450 female 2007
Adelie Torgersen 39.3 20.6 190 3650 male 2007

Table cross references (from markdown)

The presence of the caption (A few penguins) and label (#tbl-penguins) make this table referenceable:

Markdown:

See @tbl-numbers for data on a few penguins.

| Right | Left |
|------:|:-----|
|   12  |  12  |
|  123  |  123 |

: An array of numbers {#tbl-numbers}

Output:

See Table 2 for data on a few penguins.

Table 2: An array of numbers
Right Left
12 12
123 123

Your turn

  • Open tables-figures.qmd.
  • Follow the instructions in the document.
  • Exchange one new thing you’ve learned with your neighbor.
08:00

Quarto Elements


What you’re about to see . . .

  • Extends the type of elements you can add to a doc
  • Will work across the main output formats (html, pdf, docx, pptx)

Ingredients

Fenced Div and Bracketed Span

The Bracketed Span

The Bracketed Span

The Bracketed Span

The Bracketed Span

The Bracketed Span

The Bracketed Span

The Fenced Div

Example: Callout Blocks

Use case: highlight content for the reader in multiple formats.

Markdown

:::{.callout-note}
Look - a squirrel!
:::

:::{.callout-important}
Look - a squirrel!
:::

:::{.callout-tip}
Look - a squirrel!
:::

HTML output

Note

Look - a squirrel!

Important

Look - a squirrel!

Tip

Look - a squirrel!

Callout Blocks

Highlight content for the reader in multiple formats.

Markdown

:::{.callout-note}
Look - a squirrel!
:::

:::{.callout-important}
Look - a squirrel!
:::

:::{.callout-tip}
Look - a squirrel!
:::

pdf output

Callout Blocks

Highlight content for the reader in multiple formats.

Markdown

:::{.callout-note}
Look - a squirrel!
:::

:::{.callout-important}
Look - a squirrel!
:::

:::{.callout-tip}
Look - a squirrel!
:::

docx output



Code

R Markdown’s Code Chunk

```{r, echo=FALSE}
rnorm(3)
```

What syntax is being used in echo=FALSE?

  1. HTML
  2. Pandoc attribute syntax
  3. YAML
  4. CSS
  5. R

Generalizing the Code Chunk

How can this be generalized to other languages?

```{r, echo=FALSE}
rnorm(3)
```

Generalizing the Code Chunk

How can this be generalized to other languages?

```{language, echo=FALSE}
code
```
  • Executable code flagged by {}
  • Support R, Python, Julia
  • Also support mermaid and dot diagram languages.

Generalizing the Code Chunk

How can this be generalized to other languages?

```{language}
#| echo: false

code
```
  • Executable code flagged by {}
  • Support R, Python, Julia
  • Also support mermaid and dot diagram languages1
  • Cell options live inside the cell after #| (the hash pipe!)2

This is a Quarto Code Cell.

The Perks of the Hashpipe #|

  1. Line breaks prevent chunk options that go on {r, and=on, and=on, and=on, and=on, and=on, and=on}
  1. Chunk options are now pan-language with <commentchar>|.
```{python}
#| echo: false
```
```{mermaid}
%%| echo: false
```
  1. No more yelling! (eval=FALSE)

Execution Options

Control how the code is executed with options.

Option Description
eval Evaluate the code chunk (if false, just echos the code into the output).
echo Include the source code in output
output Include the results of executing the code in the output (true, false, or asis to indicate that the output is raw markdown and should not have any of Quarto’s standard enclosing markdown).
warning Include warnings in the output.
error Include errors in the output.
include Catch all for preventing any output (code or results) from being included (e.g. include: false suppresses all output from the code block).



Don’t forget to use cmd-space to see the available options!

From Cell Option to YAML

---
title: My Doc
format: html
---

```{r}
#| echo: true

pi + 1
```

From Cell Option to YAML

---
title: My Doc
format: html
execute:
  echo: true
---

```{r}
pi + 1
```
  • Options can be moved into YAML under the execute key to apply to all chunks. Exceptions to that option can be set cell-by-cell.

From Cell Option to YAML

---
title: My Doc
format: html
execute:
  echo: true
knitr:
  opts_chunk: 
    collapse: true
---

```{r}
pi + 1
```
  • Options can be moved into YAML under the execute key to apply to all chunks. Exceptions to that option can be set cell-by-cell.

  • You can also pass options via YAML to knitr through the knitr key1.

From Cell Option to YAML

---
title: My Doc
format: html
execute:
  echo: true
knitr:
  opts_chunk: 
    collapse: true
    R.options:
      digits: 2
---

```{r}
pi + 1
```
  • Options can be moved into YAML under the execute key to apply to all chunks. Exceptions to that option can be set cell-by-cell.

  • You can also pass options via YAML to knitr through the knitr key1.

  • You can use knitr to pass options that control your R session.

Example: Figures from Code

```{r}
library(palmerpenguins)
library(ggplot2)

ggplot(penguins, aes(x = bill_length_mm,
                     y = bill_depth_mm,
                     col = island)) +
  geom_point()
```

Example: Figures from Code

```{r}
#| fig-width: 5
#| fig-height: 3

library(palmerpenguins)
library(ggplot2)

ggplot(penguins, aes(x = bill_length_mm,
                     y = bill_depth_mm,
                     col = island)) +
  geom_point()
```

Example: Figures from Code

```{r}
#| fig-width: 5
#| fig-height: 3
#| fig-cap: "Size of penguins on three islands in the Palmer Archipelago."
#| fig-alt: "Scatterplot showing the bill sizes of penguins across three islands."

library(palmerpenguins)
library(ggplot2)

ggplot(penguins, aes(x = bill_length_mm,
                     y = bill_depth_mm,
                     col = island)) +
  geom_point()
```

Scatterplot showing the bill sizes of penguins across three islands.

Size of penguins on three islands in the Palmer Archipelago.

Save time/code by moving figure sizing defaults up to the YAML.

Your turn

  • Open callout-boxes.qmd and render the document.
  • Change the type of the first callout box and then re-render. Also try adding attributes inside { } to learn what they do.
    • icon=true or icon=false.
    • appearance="simple" (can also try "minimal" and "default").
  • Make the second callout box collapsible.
  • Change the format to PDF and re-render.
05:00

Your turn

  • Open code-cells.qmd and render the document.
  • Add echo: false to the code cell and re-render.
  • Add more cell options by using Ctrl + Space after the #| or consult the Quarto Reference.
  • Add a second code cell (you can copy + paste the first), move your cell options to the YAML, and re-render.
  • When we get back from breakout rooms, please share in chat your favorite trick when working with cell options.
07:00