Quarto, Quickly

A Quarto file is nothing more than a text file ending with .qmd and formatted with a header and simple Markdown. And yet, for the way it combines text and code, Quarto excels at documenting a project or analysis. By allowing explanation to live beside data, a .qmd file joins methods, results, and discussion with a number of strengths:

  1. Documents can be rendered into many file formats.
  2. Code management is well suited to reproducible project workflows.
  3. Multilingual options support the best tool for each task and practitioner.
  4. When needed, advanced features add polish without much effort.

Read on to see how to take advantage of these four points. When ready, glance over the Markdown syntax, and check the Quarto documentation for more details. And since this page was created in Quarto, the “Source” button, above, shares the underlying .qmd file that went into its creation.

1. Favorite Formats

By default, Quarto renders documents as webpages. Adding or adjusting the format option to a particular filetype in the document header will change this behavior when a document is rendered, allowing choice among HTML webpages, PDFs, slide shows, and Microsoft Word files. For instance, to present a document as a Microsoft Word file, set the format to docx:1

---
title: "Quarto, Quickly"
format: docx
---

2. Code Considerations

Unless instructed otherwise, a Quarto file treats its content as regular text to be displayed. Code must be offset within “code chunks” that flow with the document, placing their output where they lie. Demarcate a code chunk with three back ticks at the first and last line, and indicate the code language in brackets within the first of these “code fences”:2

```{r}
x <- 42
```

Code can also be called within regular text, for example to insert a value calculated in a code chunk. To incorporate the value of “x,” defined in a previous code chunk, add `{r} x` inline with a document’s text. When the document is rendered, Quarto will evaluate the code. In other words, text written like this…

`{r} x`,” said Deep Thought, with infinite majesty and calm.

…will end up like this:

“42,” said Deep Thought, with infinite majesty and calm.

Code will be processed whenever a file is rendered and when a chunk is run interactively in RStudio by clicking “Run Current Chunk.” This code can do anything one might run from the console, but there are some best practices to keep in mind, especially for reproducibility and for projects shared with a team.

Linking out

Custom functions that might be used by multiple projects should be defined outside of the Quarto document and referenced using the source() function. This makes life easier, since every project linking to that source code will benefit from fixes or improvements made in one place.

Load these external files early in a Quarto document before using their functions.3 Typically, source() is called in a setup chunk after calls to library() load up any necessary packages.

```{r}
#| label: setup

library(dplyr)
library(ggplot2)

source("my_functions.R")
```

Caching up

When one step of code takes a long time to run, it’s a good idea to avoid repeating it. Caching results and then reloading them will simplify document renders and speed things up. To cache results from one code chunk, add #| eval: false to the header of that code chunk, use saveRDS() to save the output to a file, and run the chunk interactively by clicking “Run Current Chunk.”

```{r}
#| eval: false
#| label: cache-save

my_output <- some_long_process()

saveRDS(my_output, "my_data.rds")
```

Load this RDS file in a subsequent code chunk, and continue the process from there:

```{r}
#| label: cache-load

my_output <- readRDS("my_data.rds")
```

Upon rendering, Quarto will skip the first of these two code chunks and jump directly to the second.

3. Polyglottal Possibilities

Quarto offers multilingual support for many code languages, including R, Python, SQL, Julia, Observable, and some others. What’s more, these languages can be combined in one document. This feature is especially helpful when a team includes members with strengths beyond just R or if some step of a workflow is better suited to a different language.

Using R

Code chunks using R should already be familiar. Anything indicating {r} in the top line of the code fence will be evaluated as R code.4

```{r}
#| label: fig-r
#| fig-cap: "A figure made using R code"

library(tidyverse)

ggplot(airquality, aes(Temp, Ozone)) + 
  geom_point() + 
  geom_smooth(method = "loess")
```
Figure 1: A figure made using R code

Using Python

Writing Python in a code chunk is just as easy. Change the language identifier in the first line to {python}.5

```{python}
#| label: fig-python
#| fig-cap: "A figure made using Python code"

import numpy as np
import matplotlib.pyplot as plt

radius = np.arange(0, 2, 0.01)
theta = 2 * np.pi * radius
fig, ax = plt.subplots(
  subplot_kw = {'projection': 'polar'} 
)
ax.plot(theta, radius)
ax.set_rticks([0.5, 1, 1.5, 2])
ax.grid(True)
plt.show()
```
Figure 2: A figure made using Python code

Using SQL

Because it needs to connect to a source, SQL requires a short setup in Quarto to establish a connection. Shown below, this example uses R to create a connection, my_connection, to a database management system (DBMS).6 This connection is then used in the subsequent code chunk.

```{r}
#| label: sql-setup

library(DBI)
library(RSQLite)
library(dbplyr)

my_connection <- dbConnect(SQLite(), 
                           dbname = ":memory:")

copy_to(dest = my_connection, 
        df = mtcars, 
        name = "mtcars")
```

To use SQL, change the language identifier to {sql} and add a connection: argument indicating that my_connection should be used.

```{sql}
#| label: tbl-sql
#| tbl-cap: "A table of values"
#| connection: my_connection

SELECT *
FROM mtcars
```
Table 1: A table of values
Displaying records 1 - 10
mpg cyl disp hp drat wt qsec vs am gear carb
21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4
24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2
19.2 6 167.6 123 3.92 3.440 18.30 1 0 4 4

Sharing Variables

To reference a Python variable in an R code chunk, load the reticulate package, and treat the Python environment as a named list held in the py object, as shown here with py$radius and py$theta:

```{r}
#| label: variable-sharing-r

library(reticulate)

spiral_df <- 
  data.frame(
    radius = py$radius,
    theta = py$theta)

spiral_df
```

To load an R variable in Python, reference the R environment as an object named r:

```{python}
#| label: variable-sharing-python

r.spiral_df
```
     radius      theta
0      0.00   0.000000
1      0.01   0.062832
2      0.02   0.125664
3      0.03   0.188496
4      0.04   0.251327
..      ...        ...
195    1.95  12.252211
196    1.96  12.315043
197    1.97  12.377875
198    1.98  12.440707
199    1.99  12.503539

[200 rows x 2 columns]

4. Refined Reports

When needed, Quarto provides easy polish to a report, automating processes that might otherwise add time and frustration. The Quarto documentation details many options, including how to enable a table of contents, choosing a theme, rendering to multiple formats, and more.

Adding footnotes, cross references, and citations are just three ways to add some of this polish. These options might not be necessary for every project, but they’re available whenever needed.

Footnotes

In Quarto, footnotes can be added to text in two steps. First, indicate where the footnote marker should go by adding [^footnote-name] in the text. Next, start a new paragraph with the same detail followed by a colon and a space, like this:

[^footnote-name]: Here's where the footnote's text will go.

Footnote names should only be used once per document. Each footnote gets linked automatically when rendered.7

Cross references

The label name from any chunk producing output is available to cross reference in the text.8 Start these cross references with an @ sign, and then include the label name. For example, @fig-r will show as Figure 1, pointing to the figure created using R. Other cross references also work, including Figure 2 for the figure made using Python, and Table 1 for the table made using SQL.

Citations

To cite references in Quarto, add a line referencing a .bib file in the YAML header. These .bib files can range in complexity and can be quite simple, as shown in the file used for this report, or complex, as shown in online documentation.

---
title: "Quarto, Quickly"
bibliography: references.bib
---

Reference sources using a combination of [ square brackets ], the @ sign, and the citekey, like this: [@quarto-using-r]. This citation will render in text with parentheses (Posit 2022b).

An ordered bibliography to everything cited will automatically be added at the end of the document. See more about customizing the format in the Quarto documentation.

Conclusions

Quarto is simple but powerful. It’s useful for casual things like taking notes to document a process, but it can also be used for preparing advanced, publication-ready reports. What’s more, it has support for many languages.

Start working in Quarto by preparing an outline. Keep code with text, and simplify project workflows for better reproducibility. Choose an output format, combine languages, and experiment with referencing features that are surprisingly easy to use—or keep everything painless by sticking to defaults.

Show flowchart code
```{mermaid}
%%| code-fold: true
flowchart LR
  subgraph formats["`format: 
  _html_, _docx_, _pdf_, 
  _ppt_, _revealjs_, 
  etc...`"]
  Quarto(["Quarto"])
  end
  Quarto --> Code{code}
  Code -- R --> R["{r}"]
  R -. "script" .- functions["source()"]
  R -. "data" .- data["loadRDS()"]
  Code-- Python --> P["{python}"]
  Code -- SQL --> SQL["{r}"]
  SQL -- "define" --> connection[("my_db")]
  connection --> sql2["`{sql} 
  #| connection: my_db`"]
  Quarto --> Text[text]
  Text -. footnotes .- W["Some text.[^fn1]
  [^fn1]: Some note"]
  Text -. "references" .- X["See @fig-four"]
  Text -. citations .- Y["Some text [@key]."]
  style formats fill:#fff,stroke:#fff
  style sql2 text-align:left
```

flowchart LR
  subgraph formats["`format: 
  _html_, _docx_, _pdf_, 
  _ppt_, _revealjs_, 
  etc...`"]
  Quarto(["Quarto"])
  end
  Quarto --> Code{code}
  Code -- R --> R["{r}"]
  R -. "script" .- functions["source()"]
  R -. "data" .- data["loadRDS()"]
  Code-- Python --> P["{python}"]
  Code -- SQL --> SQL["{r}"]
  SQL -- "define" --> connection[("my_db")]
  connection --> sql2["`{sql} 
  #| connection: my_db`"]
  Quarto --> Text[text]
  Text -. footnotes .- W["Some text.[^fn1]
  [^fn1]: Some note"]
  Text -. "references" .- X["See @fig-four"]
  Text -. citations .- Y["Some text [@key]."]
  style formats fill:#fff,stroke:#fff
  style sql2 text-align:left

References

Posit. 2022a. “Quarto – Using Python.” https://quarto.org/docs/computations/python.html.
———. 2022b. “Quarto – Using r.” https://quarto.org/docs/computations/r.html.
tsadigov, and gsapijaszko. 2022. “SQL Errors While Rendering Quarto.” https://community.rstudio.com/t/sql-errors-while-rendering-quarto/147671.

Footnotes

  1. Other format options are documented online.↩︎

  2. As shown in the rest of this document, options can be defined in parameters at the start of a code chunk. The online documentation explains their use.↩︎

  3. Use relative paths when pointing to external scripts. Here, the “my_functions.R” file must be in the same folder as the current Quarto document. If setting relative paths gets hard, consider using the here package to simplify things.↩︎

  4. This R example is mildly adapted from Quarto documentation (Posit 2022b).↩︎

  5. This Python example is also adapted from Quarto documentation (Posit 2022a).↩︎

  6. This SQL example is adapted from Posit Community (tsadigov and gsapijaszko 2022).↩︎

  7. Here’s where the footnote’s text will go.↩︎

  8. Be sure to start the label name with a relevant prefix. Figures should start with fig- and tables should use tbl-. Quarto defines a number of these special prefixes, documented online.↩︎