2  Dynamic: Quarto docs

Learning Objectives

Use the Quarto document preparation system to create dynamic documents that combine text and code. Learn how to share these documents with colleagues.

2.1 Install quarto

Ensure you have the quarto R package installed. Look in RStudio’s Packages pane and install if not found when searching for “quarto”.

Additionally, you can install the Quarto Command Line Interface (CLI). This will allow you to run Quarto from the command line and includes additional features not included with the R package. See the quarto setup section for more info.

2.2 Quarto overview

Quarto is a relatively new document preparation system that lets you create reproducible and dynamic content that is easily shared with others. Quarto is integrated with RStudio and allows you to combine plain text language with analysis code in the same document.

Quarto belongs to a class of literate programming tools called dynamic documents (Knuth 1984). It is not the first of its kind, but it builds substantially on its predecessors by bridging multiple programming langues.

Advantages of creating analyses using Quarto include:

  1. Clear demonstration of a workflow using plain text and code
  2. Reproducible materials allow others to use your work
  3. Easily shared content (e.g., on GitHub)
  4. Keeping the data, analysis, and writing all in the same place

This next section will run through the very basics of creating a Quarto document, some of the options for formatting, and how to generate shared content. You’ll follow along in this module.

  1. Create a new project in RStudio, first open RStudio and select “New project” from the File menu at the top.

    Then select “New Directory”. Create a directory in a location that’s easy to find.

  2. Open a new Quarto file from the File menu under New file > Quarto Document.

    Enter a title for the document (e.g., “Quarto practice”) and your name as the author. Use the defaults for the other options and hit “Create”.

    Save the file in the project root directory (give it any name you want).

  3. Let’s get familiar with the components of a Quarto document.

    Tip

    The three main components of a Quarto document are:

    • YAML
    • Code chunks
    • Plain or Markdown text

    The new file includes some template material showing the main components of a Quarto document. The content at the top is called YAML, which defines global options for the document.

    ---
    title: "Quarto practice"
    author: "Marcus Beck"
    editor: visual
    ---

    You’ll also notice that there’s a button on the top-left that lets you toggle between “source” or “visual” editor mode. The source editor simply lets you add text to the document, whereas the visual editor lets you add content that is partially rendered. First time Quarto users may prefer the visual editor.

    Using the visual editor, we can insert a code chunk (or code cell). This can be done by selecting the appropriate option from the Insert menu. Note the variety of programming langues that can be used with the code chunk.

    We can enter any code we want in the code chunks, including options for how the code chunk is evaluated. Options are specified using the hashpipe notation, #|.

    ```{r}
    #| echo: true
    print('Hello Quarto!')
    ```

    When the file is rendered, the code is run and results displayed in the output. There are many options to change how code chunks are executed, which we’ll discuss below.

    print('Hello Quarto!')
    [1] "Hello Quarto!"

    We can also run the code chunks separately without rendering the file using the arrow buttons on the top right in the source document. This can be useful for quickly evaluating your code as you include it in the file.

    Tip

    Code chunks are executed in the order they appear in the document when a .qmd file is rendered.

    Descriptive text can be entered anywhere else in the file. This is where we can describe in plain language what our analysis does or any other relevant information. Text can be entered as-is or using simple markdown text that can format the appearance of the output. If you’re using the visual editor, you can use some of the items in the file menu to modify the text appearance. In the source editor, you can manually enter markdown text:

    
    I  can write anything I want right here. Here's some **bold text**.
    
    I can also make lists
    
    1. Item 1
    1. Item 2
    
    

    When the file is rendered, the markdown text will be formatted. The text will already be formatted if you’re using the visual editor:

    I can write anything I want right here. Here’s some bold text.

    I can also make lists

    1. Item 1
    2. Item 2
  4. Render the .qmd file to the output format.

    The source file is a .qmd document. We need to render the document to create the output format - HTML (default), PDF, or Word. The following happens when you hit the render button at the top.

    Here’s what your RStudio session should look like (note the three parts of the source .qmd document - YAML, code chunk, and Markdown text). The rendered HTML file will appear in the Viewer pane on the right.

    Tip

    A rendered Quarto document as an HTML, PDF, Word, or other file format is stand-alone and can be shared with anybody!

Exercise

Repeat the above steps to create an RStudio project and Quarto file.

  1. Create an RStudio project (skip if using Posit Cloud)
  2. Open a new Quarto file
  3. Create a code chunk and add some R code
  4. Add some Markdown text outside of the code chunk
  5. Render your document to marvel at your work

This is an example of what your Quarto file might look like:

---
title: "Quarto practice"
author: "Marcus Beck"
editor: visual
---

I  can write anything I want right here. Here's some **bold text**.
    
I can also make lists
    
1. Item 1
1. Item 2
    
```{r}
#| echo: true
print('Hello Quarto!')
```

2.3 Code chunk options

The behavior of the code chunks when the file is rendered can be changed using the many options available in Quarto. This can be useful for a few reasons.

  1. Only displaying the output of a code chunk (e.g., a plot)
  2. Only displaying the code and not running the chunk
  3. Running the code without displaying output for use in other parts of the document
  4. Suppressing warnings and messages
  5. Defining table or figure options (e.g., height, width, captions, etc.)

Code chunk options can be applied globally to all chunks in the document or separately for each chunk.

To apply them globally, they’ll look something like this in the YAML, where options are added after execute:

---
title: "My Document"

execute: 
  echo: false
  warning: false
---
Tip

Be careful with indentation in the YAML, the document won’t render if the indentation is incorrect.

To apply to individual code chunks, use the #| (hashpipe) notation at the top of the code chunk. This will override any global options if you’ve included them in the top YAML. Below, echo: true indicates that the code will be displayed in the rendered output.

```{r}
#| echo: true
plot(1:10)
```

Here’s a short list of other useful execution 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 (note that this implies that errors executing code will not halt processing of the document).
include Catch all for preventing any output (code or results) from being included (e.g. include: false suppresses all output from the code block).
message Include messages in rendered output

R code can also be executed “inline” outside of code chunks. This can be useful if you want to include statements that reference particular values or information that is linked directly to data. Inline R code is entered using the r syntax followed by code.


I can enter inline text like `r 1 + 1`.

Text with inline R code will look like this when the document is rendered.

I can enter inline text like 2.

2.4 Figures and tables

Figures and tables are easily added in Quarto, created using R code or importing from an external source.

Any figures created in code chunks will be included in the rendered output. Some relevant code chunk options for figures include fig-height, fig-width, fig-cap, label (for cross-referencing) and fig-align.

```{r}
#| label: fig-myhist
#| fig-height: 4
#| fig-width: 6
#| fig-cap: "Here's my awesome histogram."
#| fig-align: "center"
vals <- rnorm(100)
hist(vals)
```
vals <- rnorm(100)
hist(vals)

Figure 2.1: Here’s my awesome histogram.

Figures can be cross-referenced in the text using the @ notation with the figure label.

Here's a cross-reference to @fig-myhist.

When the file is rendered, the appropriate figure number will be displayed with a link to the figure:

Here’s a cross-reference to Figure 2.1.

Similarly, tabular output can be created inside code chunks.

```{r}
#| label: tbl-mytable
#| tbl-cap: "Here's my awesome table."
totab <- data.frame(
  Species = c('Oysters', 'Seagrass', 'Sand'),
  Count = c(12, 5, 4)
)
knitr::kable(totab)
```
totab <- data.frame(
  Species = c('Oysters', 'Seagrass', 'Sand'),
  Count = c(12, 5, 4)
)
knitr::kable(totab)
Table 2.1: Here’s my awesome table.
Species Count
Oysters 12
Seagrass 5
Sand 4

And a cross-reference:

Here's a cross-reference to @tbl-mytable.

Here’s a cross-reference to Table 2.1.

Tip

Label tags for tables and figures must include the tbl- or fig- prefix for proper cross-referencing.

Figures can also be imported from an external source (e.g., from your computer or the web) using the ![]() notation. You can also simply add a figure from the file menu using the Visual editor.

![](figs/quarto/oysters.jpg)

You can also add a figure from a URL using the same notation.

![](https://unsplash.com/photos/HH-MuVCKal0)

Adding captions and labels to external figures looks something like this:

![Here are some beautiful oysters.](figs/quarto/oysters.jpg){#fig-oysters}

Figure 2.2: Here are some beautiful oysters.

The cross-reference is done the same.

Here's a cross-reference to @fig-oysters

Here's a cross-reference to Figure 2.2.

Likewise, tables can be imported from an external source (e.g., Excel). You’ll want to do this in a code chunk and add the appropriate options (e.g., to cross-reference Table 2.2).

```{r}
#| label: tbl-habitats
#| tbl-cap: "The first six rows of our tidy data"
mytab <- readxl::read_excel('data/tidy.xlsx')[1:6, ]
knitr::kable(mytab)
```
mytab <- readxl::read_excel('data/tidy.xlsx')[1:6, ]
knitr::kable(mytab)
Table 2.2: The first six rows of our tidy data
Location Habitat Year Acres Category
Clear Bay Seagrass 2019 519 B
Clear Bay Oysters 2019 390 B
Clear Bay Sand 2019 742 C
Fish Bay Seagrass 2019 930 B
Fish Bay Oysters 2019 680 A
Fish Bay Sand 2019 611 A

Visit these links for full details on figures and tables in Quarto. R also has a rich library of packages for producing tables, most of which play nice with Quarto.

Exercise

Create some tables, figures, and cross-references as above.

  1. In the same file from the first exercise, create a code chunk and add some R code to create a simple plot (e.g., hist(mtcars$mpg))
  2. Give the code chunk a label and figure caption
  3. Use the figure label to add a cross-reference outside of the code chunk
  4. Repeat the above, but this time create a table (e.g., knitr::kable(mtcars))
  5. Render your document to marvel at your work

This is an example of what your Quarto file might look like:

---
title: "Quarto practice"
author: "Marcus Beck"
editor: visual
---

I  can write anything I want right here. Here's some **bold text**.
    
I can also make lists
    
1. Item 1
1. Item 2
    
```{r}
#| echo: true
print('Hello Quarto!')
```

@fig-myhist shows an awesome histogram. 

```{r}
#| label: fig-myhist
#| fig-cap: "Here's my awesome histogram."
hist(mtcars$mpg)
```

@tbl-mytable shows an awesome table. 

```{r}
#| label: tbl-mytable
#| tbl-cap: "Here's my awesome table."
knitr::kable(mtcars)
```

2.5 Quarto using htmlwidgets

The htmlwidgets package allows you to embed dynamic components directly into a Quarto HTML page. There are several packages that use htmlwidgets to automatically embed the required JavaScript visualization libraries. This does not require any knowledge of JavaScript, nor use of a Shiny Server.

2.5.1 leaflet

The leaflet package can be used to create interactive maps (also see mapview for an “out-of-the-box” option). Here’s a quick map of where we are - click on the marker to view the popup.

library(leaflet)

leaflet() %>%
  addTiles() %>%  # Add default basemap tiles
  addMarkers(lng = -122.663, lat = 45.529, popup = "CERF 2023 conference")

2.5.2 plotly and dygraphs

The plotly and dygraphs packages allow you to create interactive plots. They provide similar functionality, but serve different purposes.

library(plotly)
library(tibble)

# data to plot
toplo <- tibble(
  Species = c('Oysters', 'Seagrass', 'Sand'),
  `Clear Bay` = c(12, 5, 4), 
  `Fish Bay` = c(6, 7, 9)
)

# make a plotly plot
fig <- plot_ly(toplo, x = ~Species, y = ~`Clear Bay`, type = 'bar', name = 'Clear Bay')
fig <- fig %>% add_trace(y = ~`Fish Bay`, name = 'Fish Bay')
fig <- fig %>% layout(yaxis = list(title = 'Count'), barmode = 'group')

fig

The plotly package has an additional feature that can easily transform existing ggplot objects into plotly objects using the ggplotly() function. This works fairly well for simple plots, although it is usually a better option to build plotly plots from scratch.

library(ggplot2)
library(tidyr)

# data to plot
toplo <- tibble(
    Species = c('Oysters', 'Seagrass', 'Sand'),
    `Clear Bay` = c(12, 5, 4), 
    `Fish Bay` = c(6, 7, 9)
  ) %>% 
  pivot_longer(-Species, names_to = 'Bay', values_to = 'Count')

# make a ggplot
fig <- ggplot(toplo, aes(x = Species, y = Count, fill = Bay)) + 
  geom_bar(stat = 'identity', position = 'dodge')

# conver to plotly
ggplotly(fig)

Plotly also works well for three-dimensional plotting. Here we show a bathymetric map of Tampa Bay. The input file is a raster object converted to a matrix (see here)

library(plotly)

# file created from a DEM, see 
load(file = 'data/demmat.RData')

plot_ly(z = ~demmat) %>% 
  add_surface(colorbar = list(title = 'Depth (m)'))