R Markdown Lesser-Known Tips & Tricks #4: Looks Better, Works Better

Thumbnail A half-knitted object with a two spools of yarn and a knitting needle.

Photo by rocknwool on Unsplash

The R Markdown file format combines R programming and the markdown language to create dynamic, reproducible documents. Authors use R Markdown for reports, slide shows, blogs, books — even Shiny apps! Since users can do so much with R Markdown, it’s important to create high-quality documents that take advantage of available features.

We asked our Twitter friends the tips and tricks that they have picked up along their R Markdown journey. There was a flurry of insightful responses ranging from organizing files to working with YAML, and we wanted to highlight some of the responses so that you can apply them to your work, as well.

This is the final post of a four-part series to help you on your path to R Markdown success, where we discuss how to make your document look and work better.

1. Fold code chunks by default in rendered documents

It can be distracting to show code in an R Markdown document if that is not your primary focus. Add code_folding: hide to the YAML header to hide code chunks after rendering the document:

---
title: "Code Collapse Demonstration"
output:
  html_document:
    code_folding: hide
---

```{r}
#| include = FALSE
library(dplyr)
library(ggplot2)
```

There is a negative correlation between horsepower and miles per gallon.

```{r}
mtcars %>% 
  ggplot(aes(x = hp, y = mpg)) +
  geom_point()
```

When knitted, readers can choose to unfold a code chunk by clicking the “Code” button:

 

Say that you want to hide both the code and output using a single “Code” button. The collapse chunk option collapses the source and output blocks from one code chunk into a single block. Set it to TRUE to fold this single block:

---
title: "Code Collapse Demonstration"
output:
  html_document:
    code_folding: hide
---

There is a negative correlation between horsepower and miles per gallon.

```{r}
#| include = FALSE
library(dplyr)
library(ggplot2)
```

```{r}
#| collapse = TRUE
mtcars %>% 
  glimpse()
```
 

Find out more in the R Markdown Cookbook chapter, Fold all code blocks but show some initially.

2. Add the option to download a document’s source code

In addition to folding code chunks, you can embed a “code download” button in an R Markdown document. Readers can download the source code from the rendered HTML version.

Add the following to your YAML:

output:
  html_document:
    code_download: true
R Markdown document with option to download source code by clicking a button that says Download Rmd

Interested in checking out the full list of options for html_document? You can run ?rmarkdown::html_document in your Console or refer to the help page in the rmarkdown documentation to see a complete list.

3. Turn sections into tabs

Tabsets allow you to organize information into tabs. Add .tabset to section headings to convert the lower-level headings into tabs:

---
title: "Tabset Demonstration"
output: html_document
---

```{r}
#| include = FALSE
library(dplyr)
library(ggplot2)
```

There is a negative correlation between horsepower and miles per gallon.

## Tab {.tabset}

### Plot

```{r}
mtcars %>% 
  ggplot(aes(x = hp, y = mpg)) +
  geom_point()
```

### Table

```{r}
#| collapse = TRUE
mtcars %>% 
  glimpse()
```

Readers can click between the different tabs in the tabset:

The xaringanExtra package allows you to create tabsets in a wider range of document types, such as blogdown blogs, xaringan slides, and other HTML reports.

4. Insert page breaks

Add a page break to your HTML, Word, and ODT documents with \newpage:

---
title: "Insert Page Break Demonstration"
output:
  word_document: default
---

# The first section

\newpage

# The second section
```

Note that page breaks in HTML documents will only appear when you print the page.

5. Create a multi-column page

To create a page with multiple columns, you can use pandoc’s fenced Div blocks.

---
title: "Two-column demonstration"
output: html_document
---

```{r}
#| include = FALSE
library(dplyr)
library(ggplot2)
```

This is regular text spanning the whole page. But here comes a two-column section.

::: columns
::: column
This text is in the left column.

```{r}
mtcars %>%
  ggplot(aes(x = hp, y = mpg)) +
  geom_point()
```

:::

::: column
This text is in the right column.
```{r}
#| collapse = TRUE
mtcars %>%
  glimpse()
```
:::
:::

And back to a regular single-column environment.

This results in a document that looks like this:

Rendered R Markdown document with two columns of text.

Find out more in the R Markdown Cookbook chapter, Multi-column layout.

On Pandoc fenced Div blocks

Pandoc’s fenced Div blocks are very flexible, and you can use them to customize your document in many ways. RStudio’s Visual Editor makes them easy to write. Insert a fenced Div block using the Insert shortcut, + /, and typing ‘div’. An edit button will appear at the top right when your cursor is in the block.

.Rmd file open in the RStudio IDE's visual editor with pandoc code creating two columns of text. An edit button is displayed on the top right.

Read more about fenced Div blocks in the R Markdown Cookbook chapter, Custom blocks.

6. Add internal links to different sections in your document

To link to another section of the same document, use the heading identifier:

---
title: "Internal Link Demonstration"
output: html_document
---

* Go to [table](#table)
* Go to [plot](#custom-id)

```{r}
#| include = FALSE
library(dplyr)
library(ggplot2)
```

### Plot {#custom-id}

```{r plot-caption}
mtcars %>% 
  ggplot(aes(x = hp, y = mpg)) +
  geom_point()
```

### Table

```{r}
mtcars %>% 
  glimpse()
```

Clicking on “table” will direct the reader to the ### Table heading.

The pandoc documentation lists the specifications for writing internal links. Or, you can use a custom id like [plot](#custom-id) above.

Cross-referencing is not provided within the base rmarkdown package but it is provided as an extension in bookdown. This requires a caption and a labeled code chunk and uses the syntax \@ref(type:label):

---
title: Cross-referencing a figure
output:
  bookdown::html_document2: default
---

See Figure \@ref(fig:cars-plot).

```{r cars-plot, fig.cap="The cars data.", echo=FALSE}
#| label = cars-plot
par(mar = c(4, 4, .2, .1))
plot(cars)  # a scatterplot
```

This results in a document that looks like this:

Rendered R Markdown document with a figure cross reference.

Find out more in the R Markdown Cookbook chapter, Cross-referencing within documents.

7. Create a list of words from an R-generated vector with knitr::combine_words()

For two words, knitr::combine_words() will return ‘a and b’:

letters[1:2] %>%
  knitr::combine_words()
a and b

For more than two words, knitr::combine_words() will return the list of words, including the Oxford comma by default:

letters[1:10] %>%
  knitr::combine_words()
a, b, c, d, e, f, g, h, i, and j

The glue package provides custom language engines for knitr for using glue directly in knitr chunks. Alternatively, use the epoxy package for easy templating in R Markdown documents and Shiny apps.

8. Optimize PNG plots without losing image quality

Install the OptiPNG program and include knitr::hook_optipng() in a code chunk to optimize PNG plots. The images will be recompressed to a smaller size without losing image quality.

Use the chunk option optipng = "" to enable the hook:

```{r}
knitr::knit_hooks$set(optipng = knitr::hook_optipng)
```

If you do not mind sacrificing a tiny bit quality that is barely noticable, you may also consider TinyPNG, which can optimize PNG, JPEG, and WebP images. The R function xfun::tinify() allows you to call the TinyPNG API from R to optimize images. If you want to both optimize and shrink images (which can be helpful for projects like blogdown, you may try xfun::shrink_images().

Continue the Journey

We hope that these tips & tricks help you create documents that look and work better. Thank you to everybody who shared advice, workflows, and features! It’s been amazing hearing about how others in the community use open-source tools and processes. We hope that you learned a lot (we know we did!). Check out the previous posts here:

Even though the tips & tricks series is over, there is always more to pick up on the R Markdown journey.

More On Training and Education

Stay Connected

Get updates when there's a new post.