Shiny

Building Interactive Web Applications in R






Sydney Users of R Forum (SURF)
Ian Hansel @ihansel
12th August 2013

Hansel Solutions

“ I keep saying the sexy job in the next ten years will be statisticians. People think I'm joking, but who would've guessed that computer engineers would've been the sexy job of the 1990s? ”

Hal Varian, Google Chief Economist, McKinsey Insights - January 2009

Outline

  • Introduction to Shiny
  • Simple Examples
  • Advanced Features

Why R in the browser?

  • Everyone has a browser
  • Communicate your results dynamically
  • Create custom analytics tools to explore data
  • Build your own Dashboards

???

Shiny

  • Open Sourced by RStudio November 2012
  • Not the first to get R in the browser (rApache, Rserve, Rook)
  • Default widgets and settings make it easy to generate apps
  • Don't need to know HTML, CSS and javascript to get started

Features

  • Twitter Bootstrap for default UI - looks good
  • Web sockets for communication between client and server
  • Reactive Programming model
  • Works on Windows, Mac, Linux

Reactive Programming

Similar to a spreadsheet. If you have a cell that is a function of another cell, e.g. "=A1*2", then any time A1 is updated the cell that contains that function is automatically updated.

Reactive Programming

Reactive Programming

Reactive Programming

Download and Installation

  • Install R from CRAN
  • Useful to have Chrome, Firefox, Safari or Opera as a browser
  • Rstudio - recommended
  • Install Shiny using R command:
    install.packages("shiny")
    

Hello Shiny

library(shiny)
runExample("01_hello")

server.R

# Define server logic required to generate and plot a random distribution
shinyServer(function(input, output) {
   
  # Expression that generates a plot of the distribution. The expression
  # is wrapped in a call to renderPlot to indicate that:
  #
  #  1) It is "reactive" and therefore should be automatically 
  #     re-executed when inputs change
  #  2) Its output type is a plot 
  #
  output$distPlot <- renderPlot({
        
    # generate an rnorm distribution and plot it
    dist <- rnorm(input$obs)
    hist(dist)
  })
  
})

Specifies what R is doing e.g. producing graphs, tables, modelling, etc

ui.R (User Interface)

library(shiny)

# Define UI for application that plots random distributions 
shinyUI(pageWithSidebar(
  
  # Application title
  headerPanel("Hello Shiny!"),
  
  # Sidebar with a slider input for number of observations
  sidebarPanel(
    sliderInput("obs", 
                "Number of observations:", 
                min = 0, 
                max = 1000, 
                value = 500)
  ),
  
  # Show a plot of the generated distribution
  mainPanel(
    plotOutput("distPlot")
  )
))

Controls the look and feel of the App

Layout

Layout

Input

Output

Congratulations

You now know all you need to get started building your own Shiny Apps!

ggplot2



ggplot2 - ui.R



selectInput(
 inputId='x', 
 label='X', 
 choices=
  names(dataset)
)

ggplot2 - ui.R



checkboxInput(
 inputId='jitter',
 label='Jitter'
)

ggplot2 - server.R

output$plot <- reactivePlot({

 p <- ggplot(dataset(), 
     aes_string(x=input$x, y=input$y)) +
     geom_point()

 if (input$color != 'None')
  p <- p + aes_string(color=input$color)
...
 print(p)
})

ggplot2 - server.R


print(p)

Remember to explicitly print your ggplot2 graphic if it is inside a function

ggplot2 - Data

Offer file downloads of the data/output


server.R

downloadHandler(
 filename = 'filename.csv',
 content = write.csv()
)

ui.R

downloadButton()

Custom UI

You can make your own User Interface using HTML directly.

 < application-dir >
|-- www
    |-- css
    |-- js
    |-- index.html
|-- server.R

Custom UI

Binding between shiny inputs/outputs and HTML elements is done by:


  • HTML form elements are bound using the name attribute
  •  < input type="number" name="n" value="500" min="1" max="1000" /> 
  • Output is rendered into HTML elements on id attribute
  •  < div id="plot" class="shiny-plot-output">< /div> 

Isolate

  • Sometimes you don't want things running automatically as soon as you change an input.
  • With the previous example typing in 123 for the number of points gives a graph for n=1, then n=12, then n=123
  • We can use the actionButton to get around this

Isolate

server.R

data <- reactive({       
   dist <- switch(input$dist,
           norm = rnorm,
           unif = runif,
           lnorm = rlnorm,
           exp = rexp,
           rnorm)

   input$goButton

   isolate(dist(input$n))
})

ui.R

downloadButton()

Extending Shiny

Flexible enough to work with:

  • D3 - for interactive graphics
  • Webgl - using GPU for rendering of graphics (like RGL)
  • EC2 - for publishing your app
  • Reveal - for presentations
  • more...

Demos

  • Dashboard
  • GoogleVis
  • Leaflet
  • Percept

Sharing

Sharing

  • Github
  • Package - Shiny application in inst directory
  •  shiny::runApp(system.file('appdir',
    package='packagename')) 
  • Rstudio Hosted Server
  • Self Hosted Shiny Server e.g. Amazon EC2

Amazon EC2

  • Amazon sells virtual servers called instances
  • Easy to sign up and start using
  • Do need to have knowledge about working from command line

Recap

  • Installing Shiny
  • Main Components of a Shiny App
  • Reactive Programming Model
  • How to build your own App
  • Where to look for some more advanced examples
  • Distributing your App

Thanks

  • RStudio Team - All the great work they are doing with R
  • Hakkim El Hattab - Reveal.js (look out for it in the upcoming RStudio release)
  • Jeff Allen (Trestle Technology) - Excellent examples with Shiny
  • Markus Gesmann and Diego de Castillo - GoogleVis
  • Ramnath Vaidyanathan - RCharts for interactive graphs with js

Resources

Examples

Download

To use, make sure shiny is installed. Unzip the examples folder. Then set the working directory to example you want, e.g setwd(".../examples/01_hello"). Then run starter.R or

library(shiny)
runApp()

Thanks for your Attention