9 Create Beautiful Presentations with R Markdown

Remember how we talked in Chapter 7 about the multi-tool workflow from SPSS to Excel to Word? That leaves out one of the most common tools in many people’s workflow: PowerPoint. Reporting happens in presentations as often as it does in Word-based reports.

In Chapter 7, we talked about the R Markdown-based workflow having the benefit of keeping everything in one tool. You may be wondering at this point if creating presentations will require us to add another tool, like PowerPoint. Do you need to do your analysis, data visualization, and table making in R and then copy everything to PowerPoint by hand? No! R has robust presentation-making capabilities.

In this chapter, we’ll learn how to make presentations in R using the xaringan package. This package, which uses R Markdown to make presentations, is one of several you can use to make slides, but it is the most widely used. To learn more about the capabilities of xaringan, I spoke with Silvia Canelón, a data analyst in the Urban Health Lab at the University of Pennsylvania. Canelón has done extensive teaching on the xaringan package and has thought deeply about its benefits. As you’ll hear in this chapter, these benefits include, but also go well beyond, making good-looking slides.

How xaringan Works

To get started with xaringan, you need to first install the package using the standard approach: install.packages("xaringan"). Once it is installed, you can go to File > New File > R Markdown. You’re probably thinking that you want to go to the Presentation tab. Doing so will give you several options for making slides, as you can see in Figure 9.1.

The options presented to create a new presentation

Figure 9.1: The options presented to create a new presentation

These are other formats you can use to make slides (and yes, you can knit an R Markdown document to PowerPoint). However, if you want to make a presentation with xaringan (and, as I will explain below, I think it’s the best option), you should go to the From Template tab. From there, scroll down until you find the template called Ninja Presentation. Select that, hit OK, and you’ll get a blank R Markdown document. Figure 9.2 shows you what to look for.

The options presented to create a new presentation

Figure 9.2: The options presented to create a new presentation

Just as when we created a regular R Markdown document, creating a new xaringan presentation will give us some default content. I’m going to delete that and add my own contents which you can see below.

---
title: "Penguins Report"
author: "David Keyes"
date: "2024-01-12"
output: xaringan::moon_reader
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(include = TRUE, 
                      echo = FALSE,
                      message = FALSE,
                      warning = FALSE)
```

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

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

# Introduction

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 should look familiar because it is exactly the same as the R Markdown document we created in Chapter 7 with one line changed in the YAML. Instead of output: word_document we now have output: xaringan::moon_reader. With this change, we will now get slides rather than a Word document. Let’s try hitting the Knit button to see what it looks like. When I hit Knit, I get an HTML file with the same name as R Markdown document (in my case, xaringan-example.Rmd and xaringan-example.html). If I open up the HTML document, I see Figure 9.3.

The first slide of my presentation

Figure 9.3: The first slide of my presentation

This is the first thing to know about xaringan: the slides it produces are HTML files. It may seem odd to get slides as HTML files, but it offers several advantages over formats like PowerPoint, as we’ll see below.

If we scroll to the next slide with the right arrow key, we’ll see content that looks familiar. Figure 9.4 shows this slide, which has the same text and a cut-off version of the histogram we made in Chapter 7.

The second slide of my presentation

Figure 9.4: The second slide of my presentation

At this point, we’ve learned two things about how xaringan works:

  1. The overall syntax for making slides with xaringan is nearly identical to that used to make reports with R Markdown. We copied in the content of our R Markdown document, changed one line, and we see the same output, just in slide format. The YAML, markdown text, and code chunks work exactly the same.

  2. We need to make a few tweaks to make our content fit on our slides. When we’re working in an R Markdown document that will be knitted to Word, its length doesn’t matter because reports can be one page or 100 pages. Working with xaringan, however, we need to think about how much content will fit on one slide. Our cut-off histogram shows us what happens without doing this. Let’s fix it.

Breaking Content Across Slides

Let’s make our histogram fully visible by putting it on its own slide. To make a new slide, we add three dashes at any point in our R Markdown document. I’ve copied the relevant portion of the document and added these dashes.

---

## 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()
```

If I knit again, what was one slide is now broken into two: an Introduction slide and a Bill Length slide. We can see both in Figure 9.5.

The presentation broken into two slides

Figure 9.5: The presentation broken into two slides

If I look closely, I can see that the bottom of histogram is ever so slightly cut off. I can fix this by adjusting its size. We do this using the code chunk option fig.height to make our figure four inches tall.

---

## Bill Length

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

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

Doing this makes the histogram fit on the slide and also reveals the text that was hidden below.

Incrementally Revealing Content

When presenting, it’s often useful to only show a portion of the content on each slide at a time. Let’s say, for example, we know that when we’re presenting the first slide, we want to talk a bit about each penguin species. Rather than have all three species visible when we open this slide, it would be nice to have the names come up one at a time. We can do this using what xaringan calls incremental reveal.

To use this feature, we put two dashes between any content we want to incrementally reveal. This code, for example, will let us show Adelie on the screen, then Adelie and Gentoo, then Adelie, Gentoo, and Chinstrap.

# Introduction

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

- Adelie

--

- Gentoo

--

- Chinstrap

When presenting your slides, you’ll use the right arrow to incrementally reveal the species. We can see what this looks like in Figure 9.6.

One slide shown with incremental reveal

Figure 9.6: One slide shown with incremental reveal

Aligning Content

When designing your presentation, you’ll also likely want to control the alignment of content. We do this by adding what are known as content classes. You can surround any content with the classes .left[], right[], and center[] to align them. For example, on our slide that creates a histogram and associated text, we could put .center[] around the code chunk that makes the histogram:

## Bill Length

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

.center[
```{r fig.height = 4}
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.

Doing this would center the chart on our slide, as we can see in Figure 9.7.

A slide with the chart centered

Figure 9.7: A slide with the chart centered

There are also built-in options to make two-column layouts. Adding pull-left[] and pull-right[] in this way will make two equally spaced columns.

## Bill Length

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

.pull-left[
```{r fig.height = 4}
penguins %>% 
  ggplot(aes(x = bill_length_mm)) +
  geom_histogram() +
  theme_minimal()
```
]

.pull-right[
```{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.
]

We can see what this looks like in Figure 9.8 below.

A slide with two columns

Figure 9.8: A slide with two columns

You can also use the content classes .left-column[] and .right-column[] to make a layout with a narrow left column and wide right column. The code below puts the text on the left and the histogram on the right.

## Bill Length

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

.right-column[
```{r fig.height = 4}
penguins %>% 
  ggplot(aes(x = bill_length_mm)) +
  geom_histogram() +
  theme_minimal()
```
]

.left-column[
```{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.
]

We can see the slide output in Figure 9.9.

A slide with a smaller left column and a larger right column

Figure 9.9: A slide with a smaller left column and a larger right column

In addition to aligning particular pieces of content on slides, we can also everything using the .left, right, and center classes. To do this, you specify the class right after the three dashes that indicate a new slide and before any content.

---

class: center

## Bill Length

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

```{r fig.height = 4}
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.

Doing this would give us a fully-centered slide, as seen in Figure 9.10 below.

A fully centered slide

Figure 9.10: A fully centered slide

You can also use the class .middle to vertically center the slide, as we’ll see in the next section.

Adding Background Images to Slides

The same syntax that we just used to center our entire slide can also enable us to add a background image. Below I’ve created a new slide, added the classes center and middle to horizontally and vertically align the content, and added a background image, surrounding the path to the image with url().

class: center, middle
background-image: url("penguins.jpg")

## Penguins

Doing this gives me a slide with a picture of penguins in the background with the text Penguins in front of it. Figure 9.11 shows the output.

A slide that uses a background image

Figure 9.11: A slide that uses a background image

Customizing our Slides Further

One issue with the slide we just made is that it’s hard to read the word “Penguins.” It would probably be best if we could make the text bigger and a different color. To do this, we need to use some CSS, the language used to style HTML documents (remember, when we knit our xaringan presentation, we end up with an HTML document). If you’re thinking, “I’m reading this book to learn R, not CSS,” don’t worry. You just have to know a bit of CSS to make tweaks to your slides.

To add custom CSS, I’m going to create a code chunk. To tell R Markdown that this code chunk contains CSS, not R, I put the text “css” in between the curly brackets. I can then add CSS like this to tell R Markdown to make the h2 (the second-level header) 150px and white. I have to add the .remark-slide-content before the h2 in order to make sure we target the specific element in our presentation (remark comes from remark.js, a JavaScript library to make presentations that xaringan uses under the hood).

```{css}
.remark-slide-content h2 {
  font-size: 150px;
  color: white;
}
```

We can see our slide in Figure 9.12.

The title slide with changes to the font to make the text more visible

Figure 9.12: The title slide with changes to the font to make the text more visible

If I wanted to change the font, I could do so with some additional CSS. The first line of this code will make a font called Inter available to use in our slides (we do this because not everyone has this font installed on their computers). The two lines I added will make the h2 use the Inter font and make it bold.

```{css}
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap');

.remark-slide-content h2 {
  font-size: 150px;
  color: white;
    font-family: Inter;
  font-weight: bold;
}
```

The slide with bold Inter font is visible in Figure 9.13.

The title slide with changes to the font to make the text more visible

Figure 9.13: The title slide with changes to the font to make the text more visible

Because xaringan slides are built as HTML documents, the sky is the limit in terms of customizing them with CSS. Of course, you have to know the ins and outs of CSS, and if you’re reading this book, you’re probably more into R than CSS.Fortunately, there are two ways you can customize your slides without knowing CSS.

The first way is to use pre-built themes. R users have made xaringan themes that you can apply to your slides to change the overall look-and-feel. If you run this code, you will get a list of all of these themes.

names(xaringan:::list_css())

Doing this will show the following output:

#>  [1] "chocolate-fonts"  "chocolate"       
#>  [3] "default-fonts"    "default"         
#>  [5] "duke-blue"        "fc-fonts"        
#>  [7] "fc"               "glasgow_template"
#>  [9] "hygge-duke"       "hygge"           
#> [11] "ki-fonts"         "ki"              
#> [13] "kunoichi"         "lucy-fonts"      
#> [15] "lucy"             "metropolis-fonts"
#> [17] "metropolis"       "middlebury-fonts"
#> [19] "middlebury"       "nhsr-fonts"      
#> [21] "nhsr"             "ninjutsu"        
#> [23] "rladies-fonts"    "rladies"         
#> [25] "robot-fonts"      "robot"           
#> [27] "rutgers-fonts"    "rutgers"         
#> [29] "shinobi"          "tamu-fonts"      
#> [31] "tamu"             "uio-fonts"       
#> [33] "uio"              "uo-fonts"        
#> [35] "uo"               "uol-fonts"       
#> [37] "uol"              "useR-fonts"      
#> [39] "useR"             "uwm-fonts"       
#> [41] "uwm"              "wic-fonts"       
#> [43] "wic"

You can then choose a theme you’d like to use. To use the theme, you adjust your YAML as follows. This code tells xaringan to use the default CSS as well as customizations made in the metropolis and metropolis-fonts CSS files (these come bundled with xaringan so you don’t need to do anything beyond installing the package to access them).

---
title: "Penguins Report"
author: "David Keyes"
date: "2024-01-12"
output:
  xaringan::moon_reader:
    css: [default, metropolis, metropolis-fonts]
---

You can see how this theme changes the look-and-feel of our slides in Figure 9.14 below.

A slide using the metropolis theme

Figure 9.14: A slide using the metropolis theme

If writing custom CSS is the totally flexible but more challenging option to tweaking your xaringan slides, using a custom theme is way simpler but a lot less flexible. A nice middle ground is to use the xaringanthemer package by Garrick Aden-Buie. This package has several built-in themes and also allows you to easily create your own custom xaringan theme. After installing the xaringanthemer package, you adjust the css line in your YAML to use the xaringan-themer.css file.

---
title: "Penguins Report"
author: "David Keyes"
date: "2024-01-12"
output:
  xaringan::moon_reader:
    css: xaringan-themer.css
---

With this in place, you can now customize your slides by using the style_xaringan() function. This function has over 60 arguments, allowing you to tweak nearly any part of your xaringan slides. To make the same changes that we made above with custom CSS, I’ll use just a few of the arguments. One particularly nice thing about the xaringanthemer package is that you can use any font available on Google Fonts by simply adding its name to header_font_family or any other similar argument (no need to run the line above that made the Inter font available to us). To make the same changes that I made with custom CSS above, I would add a code chunk at the top of my document that looks like this:

```{r}
library(xaringanthemer)

style_xaringan(
  header_h2_font_size = "150px",
  header_color = "white",
  header_font_weight = "bold",
  header_font_family = "Inter"
)
```

I could show you what my slide with the penguin image background looks like, but trust me, it’s exactly identical to the slide we made previously with custom CSS.

In Conclusion: The Advantages of xaringan

Now that we’ve discussed how to use xaringan, let’s talk a bit about why you might consider switching to it for your presentations. In my conversation with Silvia Canelón, she brought up three main reasons.

First, if you’re already working in R and R Markdown, being able to produce slides in the same tool is a game changer. Say you’ve written a report that you’ve knitted to a Word document. You can now reuse your code from that R Markdown document and use it to make figures, tables, and more in your xaringan slides.

Second, because xaringan creates slides as HTML documents, you can post them online (we’ll discuss ways to do this in Chapter 10). No need to email or print out your slides for your viewers. Just share the link to your slides and you’re done.

The third benefit of using xaringan is accessibility. As Canelón put it to me, “when [people] have the HTML version of the slides, they have some control over what it looks like.” People with limited vision are able to access HTML documents in ways that are accessible to them. They can, for example, increase the text size or use screen readers. Making presentations with xaringan isn’t just a cool trick. It also means more people can engage with your slides.