Creating elegant HTML presentations that feature R code (using slidify )

We recently overhauled our R workshop to improve the flow and add a little style. For several years we created workshop slides using Sweave, LaTeX and Beamer. The results were practical and the process worked fine but we needed something more flexible and more elegant. To that end, we ultimately used R markdown and and the R packages slidify and knitr (within RStudio) to creates slides that look more like this:

instead of like this:

oldstyle

We thought it might be helpful to share the process we used:

1. Choosing the technology

Though powerful, I have never liked using LaTeX. I find it tedious and verbose. Given the flexibility and increasing popularity of HTML/JavaScript frameworks for producing slides I was quickly convinced that this would be the way to go.

From my perspective there were two options, both of which used R markdown and the R package knitr to knit together text and R code. There was the package slidify from Ramnath Vaidyanathan and there was R presentation using RStudio. I spent a few hours comparing the two options. My sense was that going with the R presentation option would be a “smarter” choice given that RStudio has a lot of wind in its sails and would likely support R presentation for years to come. But in my initial experiments I found it harder to customize using the RStudio option and slidify seemed more flexible in it’s ability to use different JavaScript frameworks so I opted to use this package.

Caveat: I am a big RStudio fan and I’m the first to say that I did not do a comprehensive side-by-side comparison. These were my initial impressions based on a relatively quick review. I would definitely by interested in learning from others — please e-mail me with your experience.

2. Getting started

Slidify is hosted on GitHub and I found it easy to get started using the instructions on this page. After installing and loading slidify you can run:

author("slides")

to scaffold a new presentation in your working directory (within a new folder called, in this case, "slides"). It initializes a new git repository, creates a sample R markdown presentation (index.Rmd) and adds an assets folder with four subfolders (css, img, js and layouts) all of which are basically empty except for css which has one file called ribbons.css which is just sample CSS and can safely be deleted. Note that if you're not comfortable using Git you can ignore those files (and they can be safely deleted). The .gitkeep files force Git to keep the empty directories, they can also be deleted if you're not using Git.

Here is what the initial scaffolding looks like:

folders

Here is what the default R markdown file (index.Rmd) looks like:

---
title       : 
subtitle    : 
author      : 
job         : 
framework   : io2012        # {io2012, html5slides, shower, dzslides, ...}
highlighter : highlight.js  # {highlight.js, prettify, highlight}
hitheme     : tomorrow      # 
widgets     : []            # {mathjax, quiz, bootstrap}
mode        : selfcontained # {standalone, draft}
knit        : slidify::knit2slides
---

## Read-And-Delete

1. Edit YAML front matter
2. Write using R Markdown
3. Use an empty line followed by three dashes to separate slides!

--- .class #id 

## Slide 2

Note that the initial code between the two sets of three dashes is the front matter - also known as YAML (a recursive acronym that stands for "YAML Ain't Markup Language"), and is used to create initial settings that I'll discuss below.

3. Create a quick slide presentation using the defaults

To convert the sample R markdown file to an actual slide presentation you would run:

slidify("index.Rmd")

Running slidify for the first time will install a new folder called libraries which includes your chosen JavaScript framework and code highlighter. The JS framework will be responsible for the overall look and feel of your presentation and the highlighter will add syntax highlighting to your actual code. In the sample file, the default framework is io2012 and the highlighter is highlight.js.

This process also converts the R markdown to markdown (a .md file) and then to HTML so that you now have an index.html file that you can look at in your browser.

Here is the new file structure after running slidify(index.Rmd):

folders2

4. Change the look and feel: frameworks

The framework you choose controls the general design of the presentation and there are quite a few frameworks you can choose from. To change frameworks you simply change the framework setting in the YAML.

Personally, I like the RevealJS framework. You can take a look at an example presentation here. I also cleaned up the YAML a little so it now looks like:

---
title       : R crash course
framework   : revealjs
highlighter : highlight.js
hitheme     : tomorrow 
widgets     : []
mode        : selfcontained
knit        : slidify::knit2slides
---

If you re-run slidify("index.Rmd") the slides will be updated with the new styles and the new framework's components will be added to the frameworks folder. Note that the folder for any other frameworks that you experimented with will not be deleted (you need to keep this in mind if you are uploading the materials because you could end up with a lot of unused files).

5. Choose a syntax highlighter theme

The highlighter theme controls how your code is highlighted. There are dozens of styles for the highlight.js highlighter. I prefer to use the "default" style (instead of the style called tomorrow which is the default in slidify) so I make this small change to the hitheme component in the front matter.

6. Add your slide content

Three dashes separate slides. Beyond this you create content in either markdown or in raw HTML. To add your R code you would include code chunks that look like this:

```{r}
#R code goes here
```

Here is an example of a couple of slides (note that echo=5 tells knitr to execute all the code but only to show line 5).

---
title       : R crash course
framework   : revealjs
highlighter : highlight.js
hitheme     : default 
widgets     : []
mode        : selfcontained
knit        : slidify::knit2slides
---


## Zev's new workshop slides

You can write the slide in Markdown and HTML. This is **bold** (markdown) but this is also <b>bold</b> (html).

You might even include <span style="color:green; font-weight:bold">inline CSS.</span>

---

## Quick example with ggplot2


```{r, echo=5}
library(ggplot2)
data(diamonds)
diamonds<-diamonds[sample(1:nrow(diamonds),2000),]
ggplot(diamonds, aes(carat, price))+geom_point(color="firebrick")
```

7. Higher level customization

Custom CSS

I wanted to make minor tweaks to the RevealJS style like adding a little more space between the headings and the content and changing the color of the H3 headers. In order to do this you can add the style directly to the Rmd file enclosed in style tags:

<style>
.reveal h3 {
    color: #c1d192;
    text-align: left;
    padding-bottom: 10px;
    font-family: Impact, sans-serif;
}
</style>

Or you can create a separate CSS file and add it to the folder assets/css. If you create a CSS file and add it to this folder it will automatically be included when you run slidify again (you don't need to reference it). This is the approach I used because I wanted multiple presentations to use the same CSS. Here is the location of the CSS file:

folders3

Custom Layouts

You may want some of your slides to have specific layouts. For example, I wanted a few of my slides to include a specific two-column layout. To do this you would first create a mustache template with your layout. Second you save the template in assets/layouts. To use the layout in your slide presentation you reference your layout in the slides.

Here is an example of a new layout for creating two columns. This is saved as an HTML file in assets/layouts (called twocol.html):

---
layout: slide
---
{{{ slide.content }}}
<div style='float:left;width:48%;' class='centered'>
  {{{ slide.left.html }}}
</div>
<div style='float:right;width:48%;'>
  {{{ slide.right.html }}}
</div>
<div>
  {{{ slide.fullwidth.html }}}
</div>

folders4

In order to use this new layout you would use an & followed by the new layout file name suffix next to the new slide dashes (yes, this is hard to follow, see the example below). Then you reference the layout pieces with *** =XXX where XXX is the name of the layout section. As an example, I created a new layout called twocol.html with three sections left, right and fullwidth. This is what the code for the slide looks like (included in the Rmd file):

--- &twocol

### Two column example

*** =left
First plot
```{r, echo=TRUE}
ggplot(diamonds, aes(carat, price))+geom_point(color="cadetblue")
```

*** =right
Second plot
```{r, echo=TRUE}
ggplot(diamonds, aes(carat, price, color=clarity))+geom_point()
```

*** =fullwidth
Now I should go back to one column (fullwidth)

And here is what it looks like:

Incremental reveal text and lists

During a slide presentation you may want to gradually reveal elements on a slide. According to the docs you have two options. For a bulleted list you can use > * and for paragraphs you can use .fragment. Both of these worked fine with the default framework (io2012) but the bullet option did not seem to work for RevealJS. It seemed to be a bug which I reported here. The work-around until the bug gets fixed would be to add a reference to jQuery and then add the class fragment to the lists using jQuery. This is not ideal but it works -- here is the full code including the jQuery reference and the addition of class fragments at the end:

---
title       : R crash course
framework   : revealjs
highlighter : highlight.js
hitheme     : default 
widgets     : []
mode        : standalone
knit        : slidify::knit2slides
---

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

## Zev's new workshop slides

You can write the slide in Markdown and HTML. This is **bold** (markdown) but this is also <b>bold</b> (html).

You might even include <span style="color:green; font-weight:bold">inline CSS.</span>

---

### Quick example with ggplot2


```{r, echo=5}
# the echo=5 tells knitr that I want all lines to run but only show #5
library(ggplot2)
data(diamonds)
diamonds<-diamonds[sample(1:nrow(diamonds),2000),]
ggplot(diamonds, aes(carat, price))+geom_point(color="firebrick")
```

--- &twocol

### Two column example

*** =left
First plot
```{r, echo=TRUE}
ggplot(diamonds, aes(carat, price))+geom_point(color="cadetblue")
```

*** =right
Second plot
```{r, echo=TRUE}
ggplot(diamonds, aes(carat, price, color=clarity))+geom_point()
```

*** =fullwidth
Now I should go back to one column (fullwidth)

--- 

> * One item
> * Two item

.fragment This is a paragraph that also gets revealed incrementally.

<script>
$('ul.incremental li').addClass('fragment')
$('ol.incremental li').addClass('fragment')
</script>

Go to live slides in next section to see the result.

Incremental reveal R code

Incrementally revealing code was a lot tougher and did not seem to have a built in option and I will not go into extreme detail on how this was accomplished. In general, I re-wrote the knitr code hooks to allow me to add a class="fragment" to code chunks. The code, which is posted on GitHub as a gist, needs to be run in a code chunk in your slides. I reference this code at the beginning of the Rmd file (in a code chunk) and then I can write the code chunk like:

```{r, class="fragment"}
# this is an R code chunk that will be revealed incrementally
x<-1:10
y<-rnorm(10)
```

CLICK ON THE BLANK SLIDE BELOW AND USE ARROW KEYS TO INCREMENTALLY REVEAL:

Incremental reveal R plots

I have not had the time to incorporate incremental reveal of R plots into the code described above for knitr hooks.

8. A couple of final notes

Finding details and answers to questions can be a challenge. There are a lot of different resources and I had a hard time figuring out what was the best one. There is slidify.org, slidify.github.io, ramnathv.github.io/slidify, github.com/ramnathv/slidify each one with different materials. For example, I had particular trouble finding the full set of possible choices for the YAML settings. What is the full list of frameworks that can be selected? Where can I find a good discussion of widgets? These are the types of questions that I had some trouble finding the answers to.

Printing to PDF was a challenge (this is not related to slidify, per se). Slidify has a great option of allowing you to compile the slides in two ways -- one is standalone and one is self contained. With self contained, all of the references and materials are locally hosted in folders so that you do not have to rely on the Internet. With standalone the images etc are all embedded in the HTML and all other references use CDNs. Nevertheless, as a fail safe I still wanted a PDF to provide to students. There is a description of how to do this at this link but I found that it was not that straightforward. I needed to add some JavaScript, delete the print.css file and remove the Bootstrap reference among other things.

Summary

I found the R markdown, slidify, knitr, RevealJS combination to be a useful set of tools to create a nice set of slides. The overhaul of my workshop slides was not without challenges, I found incrementally revealing code to be particularly challenging, but I'm pleased with the final result and the first two-day workshop where I used the slides (at UCLA) went well and the slides seemed to be appreciated.

Posted in R

4 responses

    • This is a complex question actually. Slidify, itself, is Rmarkdown and I’m not sure how you’d embed it directly. The way I’d do it is to put your HTML slidify file online somewhere and then use an iFrame to embed it (this is how I’ve done it in the blog post). Good luck.

    • Hi, I really appreciate you letting me know this. It looks like the site bl.ocks was no longer allowing me to use an iFrame. I’ve fixed this.

Leave a Reply to zev@zevross.com Cancel reply

Your email address will not be published. Required fields are marked *