Introduction
Here at STATWORX, we value reader-friendly presentations of our work. For many R users, the choice is usually a Markdown file that generates a .html or .pdf document, or a Shiny application, which provides users with an easily navigable dashboard.
What if you want to construct a dashboard-style presentation without much hassle? Well, look no further. R Studio’s package flexdashboard
gives data scientists a Markdown-based way of easily setting up dashboards without having to resort to full-on front end development. Using Shiny may be a bit too involved when the goal is to present your work in a dashboard.
Why should you learn about flexdashboard
s ? If you’re familiar with R Markdown and know a bit about Shiny, flexdashboard
s are easy to learn and give you an alternative to Shiny dashboards.
In this post, you will learn the basics on how to design a flexdashboard
. By the end of this article, you’ll be able to :
- build a simple dashboard involving multiple pages
- put tabs on each page and adjust the layout
- integrate widgets
- deploy your Shiny document on ShinyApps.io.
The basic rules
To set up a flexdashboard, install the package from CRAN using the standard command. To get started, enter the following into the console:
rmarkdown::draft(file = "my_dashboard", template = "flex_dashboard", package = "flexdashboard")
This function creates a .Rmd
file with the name associated file name, and uses the package’s flexdashboard template. Rendering your newly created dashboard, you get a column-oriented layout with a header, one page, and three boxes. By default, the page is divided into columns, and the left-hand column is made to be double the height of the two right-hand boxes.
You can change the layout-orientation to rows and also select a different theme. Adding runtime: shiny
to the YAML header allows you to use HTML widgets.
Each row (or column) is created using the ———
header, and the panels themselves are created with a ###
header followed by the title of the panel. You can introduce tabsetting for each row by adding the {.tabset}
attribute after its name. To add a page, use the (=======
) header and put the page name above it. Row height can be modified by using {.data-height = }
after a row name if you chose a row-oriented layout. Depending on the layout, it may make sense to use {.data-width = }
instead.
Here, I’ll design a dashboard which explores the famous diamonds dataset, found in the ggplot2
package. While the first page contains some exploratory plots, the second page compares the performance of a linear model and a ridge regression in predicting the price.
This is the skeleton of the dashboard (minus R code and descriptive text):
---
title: "Dashing diamonds"
output:
flexdashboard::flex_dashboard:
orientation: rows
vertical_layout: fill
css: bootswatch-3.3.5-4/flatly/bootstrap.css
logo: STATWORX_2.jpg
runtime: shiny
---
Exploratory plots
=======================================================================
Sidebar {.sidebar data-width=700}
-----------------------------------------------------------------------
**Exploratory plots**
<br>
**Scatterplots**
<br>
**Density plot**
<br>
**Summary statistics**
<br>
Row {.tabset}
-----------------------------------------------------------------------
### Scatterplot of selected variables
### Density plot for selected variable
Row
-----------------------------------------------------------------------
### Maximum carats {data-width=50}
### Most expensive color {data-width=50}
### Maximal price {data-width=50}
Row {data-height=500}
-----------------------------------------------------------------------
### Summary statistics {data-width=500}
Model comparison
=======================================================================
Sidebar {.sidebar data-width=700}
-----------------------------------------------------------------------
**Model comparison**
<br>
Row{.tabset}
-----------------------------------------------------------------------
**Comparison of Predictions and Target**
### Linear Model
### Ridge Regression
Row
-----------------------------------------------------------------------
### Densities of predictions vs. target
The sidebars were added by specifying the attribute {.sidebar}
after the name, followed by a page or row header. Page headers (========
) create global sidebars, whereas local sidebars are made using row headers (---------
). If you choose a global sidebar, it appears on all pages whereas a local sidebar only appears on the page it is put on. In general, it’s a good idea to add the sidebar after the beginning of the page and before the first row of the page. Sidebars are also good for adding descriptions of what your dashboard/application is about. Here I also changed the width using the attribute data-width
. That widens the sidebar and makes the description easier to read. You can also display outputs in your sidebar by adding code chunks below it.
Adding interactive widgets
Now that the basic layout is done let’s add some interactivity. Below the description in the sidebar on the first page, I’ve added several widgets.
```{r}
selectInput("x", "X-Axis", choices = names(train_df), selected = "x")
selectInput("y", "Y-Axis", choices = names(train_df), selected = "price")
selectInput("z", "Color by:", choices = names(train_df), selected = "carat")
selectInput("model_type", "Select model", choices = c("LOESS" = "loess", "Linear" = "lm"), selected = "lm")
checkboxInput("se", "Confidence intervals ?")
```
Notice that the widgets are identical to those you typically find in a Shiny application and they’ll work because runtime: shiny
is specified in the YAML.
To make the plots react to changes in the date selection, you need to specify the input ID’s of your widgets within the appropriate render function. For example, the scatterplot is rendered as a plotly output:
```{r}
renderPlotly({
p <- train_df %>%
ggplot(aes_string(x = input$x, y = input$y, col = input$z)) +
geom_point() +
theme_minimal() +
geom_smooth(method = input$model_type, position = "identity", se = input$se) +
labs(x = input$x, y = input$y)
p %>% ggplotly()
})
```
You can use the render functions you would also use in a Shiny application. Of course, you don’t have to use render-functions to display graphics, but they have the advantage of resizing the plots whenever the browser window is resized.
Adding value boxes
Aside from plots and tables, one of the more stylish features of dashboards are value boxes. flexdashboard
provides its own function for value boxes, with which you can nicely convey information about key indicators relevant to your work. Here, I’ll add three such boxes displaying the maximal price, the most expensive color of diamonds and the maximal amount of carats found in the dataset.
flexdashboard::valueBox(max(train_df$carat),
caption = "maximal amount of carats",
color = "info",
icon = "fa-gem")
There are multiple sources from which icons can be drawn. In this example, I’ve used the gem icon from font awesome. This code chunk follows a header for what would otherwise be a plot or a table, i.e., a ###
header.
Final touches and deployment
To finalize your dashboard, you can add a logo and chose from one of several themes, or attach a CSS file. Here, I’ve added a bootswatch theme and modified the colors slightly. Most themes require the logo to be 48×48 pixels large.
---
title: "Dashing diamonds"
output:
flexdashboard::flex_dashboard:
orientation: rows
vertical_layout: fill
css: bootswatch-3.3.5-4/flatly/bootstrap.css
logo: STATWORX_2.jpg
runtime: shiny
---
After creating your dashboard with runtime: shiny
, it can be hosted on ShinyApps.io, provided you have an account. You also need to install the package rsconnect
. The document can be published with the ‘publish to server’ in RStudio or with:
rsconnect::deployDoc('path')
You can use this function after you’ve obtained your account and authorized it using rsconnect::setAccountInfo()
with an access token and a secret provided by the website. Make sure that all of the necessary files are part of the same folder. RStudio’s publish to server has the advantage of automatically recognizing the external files your application requires. You can view the example dashboard here and the code on our GitHub page.
Recap
In this post, you’ve learned how to set up a flexdashboard
, customize and deploy it – all without knowing JavaScript or CSS, or even much R Shiny. However, what you’ve learned here is only the beginning! This powerful package also allows you to create storyboards, integrate them in a more modularized way with R Shiny and even set up dashboards for mobile devices. We will explore these topics together in future posts. Stay tuned!