Data visualization using R and Shiny

Apr. 25, 2017

Introduction

The ability to explore large-scale datasets frequently requires the use of intuitive and interactive data visualization tools to help extract knowledge and understand complex datasets. One of the most frequently used tools in bioinformatics is R - a powerful statistical programming language with strong data-mining and data visualization capabilities. It offers a set of built-in functions and libraries to analyze and present data, such as heatmaps, boxplots, and scatter and/or line plots. It can for example, generate a heatmap to represent genes exhibiting high or low expression in certain conditions. These graphs are usually static and 2 dimensional, so sharing results usually means exporting the static format.

In this blog post, I will discuss two R packages called shiny and d3heatmap, which can take the typical two-dimensional graph a step futher and generate an interactive web application graph built around your R analysis. This allows a user to inspect specific values by hovering the mouse over the cell, as well as zooming to a particular region of the graph by dragging a rectangle around the relevant area. In addition to generating publication-quality graphics, users can also share the graphs by simply sending a URL.

What is a Shiny App?

  • It does not require any HTML, Javascript or CSS knowledge, but is fully extensible and customizable with HTML/Javascript/CSS/
  • Designed to integrate with existing Javascript libraries (including d3.js)
  • Provides an elegant way to make interactive R graphics and tables available via the web. It runs a web server within R, serving up interactive pages each of which can be defined by two components:
    • ui: a user interface R script specifying the user interface connected to a computer/server running a live R session (server)
    • server: a server R script which performs the data analysis and visualization that needs to take place on the server as the user manipulate the UI
  • A shinyApp combines the ui and server components to generate a functioning app

What is d3heatmap?

  • Generates interactive heatmaps
  • Allows a user to click on rows/columns, or draw rectangles to zoom in

Creating an interactive web-based heatmap

In this example, we are going to utilize the R packages d3heatmap and shiny to generate a web-based interactive heatmap representing the percentage clinical completeness of several clinical fields across multiple ICGC projects. The input CSV file containing raw data will look similar to this:

project_codeproject_namecountryclinical_field1clinical_field2clinical_field3
PACA-CAPancreatic CancerCanada1009865
MALY-CAMalignant LymphomaGermany1008998
PRAD-JPProstate CancerJapan894523

Download Demo Example CSV File

Getting started:

Install the shiny package

Start up R and install the shiny package

> install.packages("shiny")
> library(shiny)

Install the d3heatmap package

> install.packages("d3heatmap")

Next, load the CSV file and pre-process the data

  • Read CSV file into R
  • Sort by country
  • Set row names attribute (row.names(data)) to project names
  • Store project codes in a vector called project_codes, which will be used as labels in the graph
> data<-read.csv("Demo_Clinical_Completeness_Metrics.tsv", header=TRUE, sep="\t")
> data<-data[order(data$Country),]
> row.names(data)<-data$project_name
> project_codes<-data$project_code
  • Define area of table that needs to be graphed. Store this data in a variable called “clinical_data”.
  • The heatmap function requires a data matrix, so we need to convert a data frame to data matrix
> clinical_data<-data[,3:length(data[1,])]
> clinical_data_matrix<-data.matrix(clinical_data)

Next we will create a shiny app

Create a shiny app

Shiny apps can be developed using the following template in R:

  • The fluidPage function allows the display to adjust automatically to the browser dimensions.
  • The un-named function in the server component will run once and save a distinct set of reactive objects for each new user that visits the app

app.R:

> library(shiny)
> ui <− fluidPage ()
> server <− function(input, output){}
> shinyApp(ui=ui,server=server)

In our example, we use two wrapper functions to implement d3heatmap in shiny

  • We use the wrapper function “d3heatmapOutput” in the fluidPage function to create a UI element whenever the app runs.
> ui<-fluidPage(titlePanel(title), theme=shinytheme("cerulean"), d3heatmapOutput("heatmap", height="800px", width="80%"))
  • We use the wrapper function “renderD3heatmap” to render the actual heatmap:
server <- function(input, output, session) { output$heatmap <- renderD3heatmap({d3heatmap(clinical_data_matrix, Rowv=NA, Colv=NA, col=brewer.pal(9,"Reds"), scale="none", RowSideColors=country_colours, cellnote=clinical_data, labRow=project_codes, xaxis_font_size=10, yaxis_font_size=10, height=900)})}

Final Shiny App code:

This code can be used to create a heatmap from various datasets, so we’ve wrapped the code in a function called “generate_heatmap” which looks like this:

# Heatmap_ClinicalComplete.R
library(d3heatmap)
library(RColorBrewer)
library(shiny)
library(shinythemes)

generate_heatmap<-function(fileName, title) {
   data<-read.csv(file=fileName, header=TRUE, sep="\t")
   data<-data[order(data$Country),]
   row.names(data)<-data$project_name
   project_codes<-data$project_code
   clinical_data<-data[,5:length(data[1,])]
   clinical_data_matrix<-data.matrix(clinical_data)
   ui<-fluidPage(titlePanel(title), theme=shinytheme("cerulean"), d3heatmapOutput("heatmap", height="800px", width="80%"))
   server <- function(input, output, session) { output$heatmap <- renderD3heatmap({d3heatmap(clinical_data_matrix, Rowv=NA, Colv=NA, col=brewer.pal(9,"Reds"), scale="none", cellnote=clinical_data, labRow=project_codes, xaxis_font_size=10, yaxis_font_size=10, height=900)})}
   shinyApp(ui, server)
}

To call this function in R:

> source("Heatmap_ClinicalComplete.R")
> generate_heatmap(file="Clinical_Completeness_Metrics.tsv", "Clinical Completeness")

brush-selection

Share your graph

So far, we’ve been running Shiny locally and running this app using an R session on our own computer, so this app is accessible in your own local browser. But if you want to share the app with the world, you’ll need to host it somewhere:

  • Host on shinyapps.io: RStudio provides a service called shinyapps.io which lets you host apps for free
  • Host on Shiny Server: The other option is to host your app on your own private Shiny server.

Helpful Links:

Hardeep Nahal, Bioinformatician
Bioinformatician who enjoys making sense of complicated data. Background in both bioinformatics and molecular biology with a strong desire to help cancer researchers tackle difficult problems. Strong appetite for knowledge and skittles.