10  Quarto

You are reading the free online version of this book. If you’d like to purchase a physical or electronic copy, you can buy it from No Starch Press, Powell’s, Barnes and Noble or Amazon.

Quarto, the next-generation version of R Markdown, offers a few advantages over its predecessor. First, the syntax Quarto uses across output types is more consistent. As you’ve seen in this book, R Markdown documents might use a variety of conventions; for example, xaringan indicates new slides using three dashes, which would create a horizontal line in other output formats, and the distill package likewise has layout options that don’t work in xaringan.

Quarto also supports more languages than R Markdown does, as well as multiple code editors. While R Markdown is designed to work specifically in the RStudio IDE, Quarto works not only in RStudio but also in code editors such as Visual Studio (VS) Code and JupyterLab, making it easy to use with multiple languages.

This chapter focuses on the benefits of using Quarto as an R user. It explains how to set up Quarto, then covers some of the most important differences between Quarto and R Markdown. Finally, you’ll learn how to use Quarto to make the parameterized reports, presentations, and websites covered in previous chapters.

Creating a Quarto Document

Versions of RStudio starting with 2022.07.1 come with Quarto installed. To check your RStudio version, click RStudio > About RStudio in the top menu bar. If you have an older version of RStudio, update it now by reinstalling it, as outlined in Chapter 1. Quarto should then be installed for you.

Once you’ve installed Quarto, create a document by clicking File > New File > Quarto Document. You should see a menu, shown in Figure 10.1, that looks like the one used to create an R Markdown document.

Figure 10.1: The RStudio menu for creating a new Quarto document

Give your document a title and choose an output format. The Engine option allows you to select a different way to render documents. By default, it uses Knitr, the same rendering tool used by R Markdown. The Use Visual Markdown Editor option provides an interface that looks more like Microsoft Word, but it can be finicky, so I won’t cover it here.

The resulting Quarto document should contain default content, just as R Markdown documents do:

---
title: "My Report"
format: html
---

## Quarto

Quarto enables you to weave together content and executable code into a finished document. To learn more about Quarto see <https://quarto.org>.

## Running Code

When you click the **Render** button a document will be generated that includes both content and the output of embedded code. You can embed code like this:

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

You can add options to executable code like this 

```{r}
#| echo: false
2 * 2
```

The `echo: false` option disables the printing of code (only output is displayed).

Although R Markdown and Quarto have many features in common, they also have some differences to be aware of.

Comparing R Markdown and Quarto

Quarto and R Markdown documents have the same basic structure — YAML metadata, followed by a combination of Markdown text and code chunks — but they have some variations in syntax.

The format and execute YAML Fields

Quarto uses slightly different options in its YAML. It replaces the output field with the format field and uses the value html instead of html_document:

---
title: "My Report"
output: html_document
---

Other Quarto formats also use different names than their R Markdown counterparts: docx instead of word_document and pdf instead of pdf_document, for example. All of the possible formats can be found at https://quarto.org/docs/guide/.

A second difference between R Markdown and Quarto syntax is that Quarto doesn’t use a setup code chunk to set default options for showing code, charts, and other elements in the rendered versions of the document. In Quarto, these options are set in the execute field of the YAML. For example, the following would hide code, as well as all warnings and messages, from the rendered document:

---
title: "My Report"
format: html
execute:
  echo: false
  warning: false
  message: false
---

Quarto also allows you to write true and false in lowercase.

Individual Code Chunk Options

In R Markdown, you override options at the individual code chunk level by adding the new option within the curly brackets that start a code chunk. For example, the following would show both the code 2 * 2 and its output:

```{r echo = TRUE}
2 * 2
```

Quarto instead uses this syntax to set individual code chunk–level options:

```{r}
#| echo: false
2 * 2
```

The option is set within the code chunk itself. The characters #| (known as a hash pipe) at the start of a line indicate that you are setting options.

Dashes in Option Names

Another difference you’re likely to see if you switch from R Markdown to Quarto is that option names consisting of two words are separated by a dash rather than a period. R Markdown, for example, uses the code chunk option fig.height to specify the height of plots. In contrast, Quarto uses fig-height, as follows:

```{r}
#| fig-height: 10

library(palmerpenguins)
library(tidyverse)

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

Helpfully for anyone coming from R Markdown, fig.height and similar options containing periods will continue to work if you forget to make the switch. A list of all code chunk options can be found on the Quarto website at https://quarto.org/docs/reference/cells/cells-knitr.html.

The Render Button

You can follow the same process to render your Quarto document as in R Markdown, but in Quarto the button is called Render rather than Knit. Clicking Render will turn the Quarto document into an HTML file, Word document, or any other output format you select.

Parameterized Reporting

Now that you’ve learned a bit about how Quarto works, you’ll make a few different documents with it, starting with a parameterized report. The process of making parameterized reports with Quarto is nearly identical to doing so with R Markdown. In fact, you can adapt the R Markdown document you used to make the Urban Institute COVID report in Chapter 7 for Quarto simply by copying the .Rmd file, changing its extension to .qmd, and then making a few other changes:

---
title: "Urban Institute COVID Report"
format: html
params:
  state: "Alabama"
execute:
  echo: false
  warning: false
  message: false
---

```{r}
library(tidyverse)
library(urbnthemes)
library(here)
library(scales)
```

# `r params$state`

```{r}
cases <- tibble(state.name) %>%
  rbind(state.name = "District of Columbia") %>%
  left_join(
    read_csv("https://data.rfortherestofus.com/united_states_covid19_cases_deaths_and_testing_by_state.csv", skip = 2),
    by = c("state.name" = "State/Territory")
  ) %>%
  select(
    total_cases = `Total Cases`,
    state.name,
    cases_per_100000 = `Case Rate per 100000`
  ) %>%
  mutate(cases_per_100000 = parse_number(cases_per_100000)) %>%
  mutate(case_rank = rank(-cases_per_100000, ties.method = "min"))
```

```{r}
state_text <- if_else(params$state == "District of Columbia", str_glue("the District of Columbia"), str_glue("state of {params$state}"))

state_cases_per_100000 <- cases %>%
  filter(state.name == params$state) %>%
  pull(cases_per_100000) %>%
  comma()

state_cases_rank <- cases %>%
  filter(state.name == params$state) %>%
  pull(case_rank)
```

In `r state_text`, there were `r state_cases_per_100000` cases per 100,000 people in the last seven days. This puts `r params$state` at number `r state_cases_rank` of 50 states and the District of Columbia. 

```{r}
#| fig-height: 8

set_urbn_defaults(style = "print")

cases %>%
  mutate(highlight_state = if_else(state.name == params$state, "Y", "N")) %>%
  mutate(state.name = fct_reorder(state.name, cases_per_100000)) %>%
  ggplot(aes(
    x = cases_per_100000,
    y = state.name,
    fill = highlight_state
  )) +
  geom_col() +
  scale_x_continuous(labels = comma_format()) +
  theme(legend.position = "none") +
  labs(
    y = NULL,
    x = "Cases per 100,000"
  )
```

This code switches output: html_document to format: html in the YAML, then removes the setup code chunk and sets those options in the YAML’s execute field. Finally, the fig.height option in the last code chunk is replaced with fig-height and labeled as an option with the hash pipe.

Next, to create one report for each state, you must tweak the render.R script file you used to make parameterized reports in Chapter 7:

# Load packages
library(tidyverse)
library(quarto)

# Create a vector of all states and the District of Columbia
state <- tibble(state.name) %>%
  rbind("District of Columbia") %>% 
  pull(state.name)

# Create a tibble with information on the:
# input R Markdown document
# output HTML file
# parameters needed to knit the document
reports <- tibble(
  input = "urban-covid-budget-report.qmd",
  output_file = str_glue("{state}.html"),
  execute_params = map(state, ~list(state = .))
)

# Generate all of our reports
reports %>%
  pwalk(quarto_render)

This updated render.R file loads the quarto package instead of the rmarkdown package 1 and changes the input file to urban-covid-budget-report.qmd. The reports tibble uses execute_params instead of params because this is the argument that the quarto_render() function expects. To render the reports, the quarto_render() function replaces the render() function from the rmarkdown package. As in Chapter 7, running this code should produce a report for each state.

Making Presentations

Quarto can also produce slideshow presentations like those you made in Chapter 8 with the xaringan package. To make a presentation with Quarto, click File > New File > Quarto Presentation. Choose Reveal JS to make your slides and leave the Engine and Editor options untouched.

The slides you’ll make use the reveal.js JavaScript library under the hood, a technique similar to making slides with xaringan. The following code updates the presentation you made in Chapter 8 so that it works with Quarto:

---
title: "Penguins Report"
author: "David Keyes"
format: revealjs
execute: 
  echo: false
  warning: false
  message: false
---

# Introduction

```{r}
library(tidyverse)
```

```{r}
penguins <- read_csv("https://raw.githubusercontent.com/rfortherestofus/r-without-statistics/main/data/penguins-2008.csv")
```

We are writing a report about the **Palmer Penguins**. These penguins are *really* amazing. There are three species:

- Adelie
- Gentoo
- Chinstrap

## Bill Length

We can make a histogram to see the distribution of bill lengths.

```{r}
penguins %>%
  ggplot(aes(x = bill_length_mm)) +
  geom_histogram() +
  theme_minimal()
```

```{r}
average_bill_length <- penguins %>%
  summarize(avg_bill_length = mean(
    bill_length_mm,
    na.rm = TRUE
  )) %>%
  pull(avg_bill_length)
```

The chart shows the distribution of bill lengths. The average bill length is `r average_bill_length` millimeters.

This code sets format: revealjs in the YAML to make a presentation and adds several global code chunk options in the execute section. It then removes the three dashes used to make slide breaks because firstor secondlevel headings make new slides in Quarto (though you could still use three dashes to manually add slide breaks). When you render this code, you should get an HTML file with your slides. The output should look similar to the default xaringan slides from Chapter 8.

Revealing Content Incrementally

Quarto slides can incrementally reveal content. To reveal bulleted and numbered lists one item at a time by default, add incremental: true to the document’s YAML like so:

---
title: "Penguins Report"
author: "David Keyes"
format: 
  revealjs:
      incremental: true
execute: 
  echo: false
  warning: false
  message: false
---

As a result of this code, the content in all lists in the presentation should appear on the slide one item at a time.

You can also set just some lists to incrementally reveal using this format:

::: {.incremental}
- Adelie
- Gentoo
- Chinstrap
:::

Using ::: to start and end a segment of the document creates a section in the resulting HTML file known as a div. The HTML <div> tag allows you to define properties within that section. In this code, adding {.incremental} sets a custom CSS class that displays the list incrementally.

Aligning Content and Adding Background Images

You can use a <div> tag to create columns in Quarto slides, too. Say you want to create a slide with content in two columns, as in Figure 10.2.

Figure 10.2: Creating two columns with a <div> tag

The following code creates this two-column slide:

:::: {.columns}

::: {.column width="50%"}
```{r}
penguins %>%
  ggplot(aes(x = bill_length_mm)) +
  geom_histogram() +
  theme_minimal()
```

:::

::: {.column width="50%"}
```{r}
penguins %>%
  ggplot(aes(x = bill_depth_mm)) +
  geom_histogram() +
  theme_minimal()
```

:::

::::
Notice the :::, as well as ::::, which creates nested <div> sections. The columns class tells the HTML that all content within the :::: should be laid out as columns. Then, ::: {.column width="50%"} starts a

that takes up half the width of the slide. The closing ::: and :::: indicate the end of the section.

When using xaringan, you easily centered content on a slide by surrounding it with .center[]. Alignment in Quarto is slightly more complicated. Quarto has no built-in CSS class to center content, so you’ll need to create one yourself. Begin a CSS code chunk and a custom class called center-slide:

```{css}
.center-slide {
    text-align: center;
}
```

This CSS center-aligns all content. (The text-align property aligns images, too, not just text.)

To apply the new center-slide class, put it next to the title of the slide, as follows:

## Bill Length {.center-slide}

With the custom CSS applied, the slide should now center all content.

Finally, when working in xaringan, you added a background image to a slide. To do the same thing in Quarto, apply the background-image attribute to a slide, like so:

## Penguins {background-image="penguins.jpg"}

This should add a slide with the text Penguins in front of the selected image.

Customizing Your Slides with Themes and CSS

You’ve started making some changes to the look and feel of the Quarto slides, but you can add even more customization to your design. As with xaringan, there are two main ways to further customize your slides in Quarto: using existing themes and changing the CSS.

Themes are the easiest way to change your slide design. To apply a theme in Quarto, simply add its name to your YAML:

---
title: "Penguins Report"
format:
  revealjs: 
    theme: dark
---

Using this option should change the theme from light (the default) to dark. You can see the title slide with the dark theme applied in Figure 10.3. To see the full list of available themes, go to https://quarto.org/docs/presentations/revealjs/themes.html.

Figure 10.3: A slide with the dark theme applied

The second option to change your slide design further is to write custom CSS. Quarto uses a type of CSS called Sass that lets you include variables in the CSS. These variables resemble those from the xaringanthemer package, which allowed you to set values for header formatting using header_h2_font_size and header_color.

Go to File > New File > New Text File, create a Sass file called theme.scss, and add the following two mandatory sections:

/*-- scss:defaults --*/

/*-- scss:rules --*/

The scss:defaults section is where you use the Quarto Sass variables. For example, to change the color and size of first-level headers, add this code:

/*-- scss:defaults --*/
$presentation-heading-color: red;
$presentation-h1-font-size: 150px;

/*-- scss:rules --*/

All Quarto Sass variables start with a dollar sign, followed by a name. To apply these tweaks to your slides, adjust your YAML to tell Quarto to use the custom theme.scss file:

---
title: "Penguins Reports"
format:
  revealjs: 
    theme: theme.scss
---

Figure 10.4 shows the changes applied to the rendered slides.

Figure 10.4: A slide modified using custom CSS

All predefined variables should go in the scss:defaults section. You can find the full list of these variables at https://quarto.org/docs/presentations/revealjs/themes.html#sass-variables.

The scss:rules section is where you can add CSS tweaks for which there are no existing variables. For example, you could place the code you wrote to center the slide’s content in this section:

/*-- scss:defaults --*/
$presentation-heading-color: red;
$presentation-h1-font-size: 150px;

/*-- scss:rules --*/
.center-slide {
  text-align: center;
}

Because rendered Quarto slides are HTML documents, you can tweak them however you’d like with custom CSS. What’s more, because the slides use reveal.js under the hood, any features built into that JavaScript library work in Quarto. This library includes easy ways to add transitions, animations, interactive content, and much more. The demo Quarto presentation available at https://quarto.org/docs/presentations/revealjs/demo/ shows many of these features in action.

Making Websites

Quarto can make websites without requiring the use of an external package like distill. To create a Quarto website, go to File > New Project. Select New Directory, then Quarto Website. You’ll be prompted to choose a directory in which to place your project. Keep the default engine (Knitr), check Create a Git Repository (which should show up only if you’ve already installed Git), and leave everything else unchecked.

Click Create Project, which should create a series of files: index.qmd, about.qmd, _quarto.yml, and styles.css. These files resemble those created by the distill package. The .qmd files are where you’ll add content, the _quarto.yml file is where you’ll set options for the entire website, and the styles.css file is where you’ll add CSS to customize the website’s appearance.

Building the Website

You’ll start by modifying the .qmd files. Open the home page file (index.qmd), delete the default content after the YAML, and replace it with the content from the website you made in Chapter 9. Remove the layout = "l-page" element, which you used to widen the layout. I’ll discuss how to change the page’s layout in Quarto later in this section.

To render a Quarto website, look for the Build tab in the top right of RStudio and click Render Website. The rendered website should now appear in the Viewer pane on the bottom-right pane of RStudio. If you navigate to the Files pane on the same panel, you should also see that a _site folder has been created to hold the content of the rendered site. Try opening the index.html file in your web browser. You should see the website in Figure 10.5.

Figure 10.5: The Quarto website with warnings and messages

As you can see, the web page includes many warnings and messages that you don’t want to show. In R Markdown, you removed these in the setup code chunk; in Quarto, you can do so in the YAML. Add the following code to the index.qmd YAML to remove all code, warnings, and messages from the output:

execute: 
  echo: false
  warning: false
  message: false

Note, however, that these options will make changes to only one file. Next, you’ll see how to set these options for the entire website.

Setting Options

When using distill, you modified the _site.yml file to make changes to all files in the website. In Quarto, you use the _quarto.yml file for the same purpose. If you open it, you should see three sections:

project:
  type: website

website:
  title: "covid-website-quarto"
  navbar:
    left:
      - href: index.qmd
        text: Home
      - about.qmd

format:
  html:
    theme: cosmo
    css: styles.css
    toc: true

The top section sets the project type (in this case, a website). The middle section defines the website’s title and determines the options for its navigation bar. The bottom section modifies the site’s appearance.

You’ll start from the bottom. To remove code, warnings, and messages for every page in the website, add the portion of the YAML you wrote earlier to the _quarto.yml file. The bottom section should now look like this:

format:
  html:
    theme: cosmo
    css: styles.css
    toc: true
execute: 
  echo: false
  warning: false
  message: false

If you build the website again, you should now see just the content, as in Figure 10.6.

Figure 10.6: The website with warnings and messages removed

In this section of the _quarto.yml file, you can add any options you would otherwise place in a single .qmd file to apply them across all the pages of your website.

Changing the Website’s Appearance

The format section of the _quarto.yml file determines the appearance of rendered files. By default, Quarto applies a theme called cosmo, but there are many themes available. (You can see the full list at https://quarto.org/docs/output-formats/html-themes.html.) To see how a different theme affects the output, make the following change:

format:
  html:
    theme: minty
    css: styles.css
    toc: true

The minty theme changes the website’s fonts and updates the color scheme to gray and light green.

In addition to using prebuilt themes, you can customize your website with CSS. The css: styles.css section in the _quarto.yml file indicates that Quarto will use any CSS in the styles.css file when rendering. Try adding the following CSS to styles.css to make first-level headers red and 50 pixels large:

h1 {
  color: red;
  font-size: 50px;
}

The re-rendered index.html now has large red headings (shown in Figure 10.7).

Figure 10.7: The website with custom CSS applied

An alternative approach to customizing your website is to use Sass variables in a .scss file, as you did in your presentation. For example, create a file called styles.scss and add a line like this one to make the body background bright yellow:

/*-- scss:defaults --*/
$body-bg: yellow;

To get Quarto to use the styles.scss file, adjust the theme line as follows:

format:
  html:
    theme: [minty, styles.scss]
    css: styles.css
    toc: true

This syntax tells Quarto to use the minty theme, then make additional tweaks based on the styles.scss file. If you render the website again, you should see the bright yellow background throughout (Figure 10.8).

Figure 10.8: The website with custom CSS applied through styles.scss

Note that when you add a .scss file, the tweaks made in styles.css no longer apply. If you wanted to use those, you’d need to add them to the styles.scss file.

The line toc: true creates a table of contents on the right side of the web pages (which you can see in Figure 10.5 and Figure 10.7). You can remove the table of contents by changing true to false. Add any further options, such as figure height, to the bottom section of the _quarto.yml file.

Adjusting the Title and Navigation Bar

The middle section of the _quarto.yml file sets the website’s title and navigation. Change the title and the text for the About page link as follows:

website:
  title: "Quarto COVID Website"
  navbar:
    left:
      - href: index.qmd
        text: Home
      - href: about.qmd
        text: About this Website

Changing the title requires adjusting the title line. The navbar section functions nearly identically to how it does with distill. The href line lists the files the navigation bar should link to. The optional text line specifies the text that should show up for that link. Figure 10.9 shows these changes applied to the website.

Figure 10.9: The changes to the navigation bar

The title on the home page is still covid-website-quarto, but you could change this in the index.qmd file.

Creating Wider Layouts

When you created a website with distill, you used the line layout = "l-page" to widen the map on the web page. You can accomplish the same result with Quarto by using the ::: syntax to add HTML <div> tags:

:::{.column-screen-inset}
```{r}
#| out-width: 100%
# Make map

most_recent <- us_states %>%
  left_join(covid_data, by = "state") %>%
  slice_max(
    order_by = date,
    n = 1
  )

most_recent %>%
  ggplot(aes(fill = deaths_avg_per_100k)) +
  geom_sf() +
  scale_fill_viridis_c(option = "rocket") +
  labs(fill = "Deaths per\n100,000 people") +
  theme_void()
```
:::

This code adds :::{.column-screen-inset} to the beginning of the mapmaking code chunk and ::: to the end of it. This code chunk now also includes the line #| out-width: 100% to specify that the map should take up all of the available width. Without this line, the map would take up only a portion of the window. There are a number of different output widths you can use; see the full list at https://quarto.org/docs/authoring/article-layout.html.

Hosting Your Website on GitHub Pages and Quarto Pub

You can host your Quarto website using GitHub Pages, just as you did with your distill website. Recall that GitHub Pages requires you to save the website’s files in the docs folder. Change the _quarto.yml file so that the site outputs to this folder:

project:
  type: website
  output-dir: docs

Now, when you render the site, the HTML and other files should show up in the docs directory. At this point, you can push your repository to GitHub, adjust the GitHub Pages settings as you did in Chapter 9, and see the URL at which your Quarto website will live.

As an alternative to GitHub Pages, Quarto has a free service called Quarto Pub that makes it easy to get your materials online. If you’re not a GitHub user, this is a great way to publish your work. To see how it works, you’ll publish the website you just made to it. Click the Terminal tab on the bottom-left pane of RStudio. At the prompt, enter quarto publish. This should bring up a list of ways you can publish your website, as shown in Figure 10.10.

Figure 10.10: The list of providers to publish your Quarto website

Press Enter to select Quarto Pub. You’ll then be asked to authorize RStudio to publish to Quarto Pub. Enter Y to do so, which should take you to https://quartopub.com. Sign up for an account (or sign in if you already have one). You should see a screen indicating that you have successfully signed in and authorized RStudio to connect with Quarto Pub. From there, you can return to RStudio, which should prompt you to select a name for your website. The easiest option is to use your project’s name. Once you enter the name, Quarto Pub should publish the site and take you to it, as shown in Figure 10.11.

Figure 10.11: The website published on Quarto Pub

When you make updates to your site, you can republish it to Quarto Pub using the same steps. Quarto Pub is probably the easiest way to publish HTML files made with Quarto.

Summary

As you’ve seen in this chapter, you can do everything you did in R Markdown using Quarto, without loading any external packages. In addition, Quarto’s different output formats use a more consistent syntax. For example, because you can make new slides in Quarto by adding firstor second-level headers, the Quarto documents you use to create reports should translate easily to presentations.

You’re probably wondering at this point whether you should use R Markdown or Quarto. It’s a good question, and one many in the R community are thinking about. R Markdown isn’t going away, so if you already use it, you don’t need to switch. If you’re new to R, however, you may be a good candidate for Quarto, as its future features may not be backported to R Markdown.

Ultimately, the differences between R Markdown and Quarto are relatively small, and the impact of switching between tools should be minor. Both R Markdown and Quarto can help you become more efficient, avoid manual errors, and share results in a wide variety of formats.

Additional Resources

Consult the following resources to learn the fundamentals of Quarto: