2017-04-07

Objective

Learn what the heck shiny is and how you use it!

What's Shiny?

  • An interactive report framework
  • An R package that is available free (as is the server edition)
  • Uses "modern web standards" like bootstrap under the hood

Quick example

Complex example

Complex example

Shiny structure

Contents

Typical

A shiny application report consists of two functions1

  • shinyServer()
  • shinyUI()

One says what to execute and the other states how to present it the results.

Contents

"Lite"

defaultdisplay<-list(width="100%", height="75%")

shinyApp(
    ui      = fluidPage()
  , server  = function(input, output) {}
  , options = defaultdisplay
)

Files

You typically split into two files:

  • server.R containing shinyServer()
  • ui.R containing shinyUI()

This can then be run with runApp()

You can do a single file example app.R which contains both functions but this is typically better for very short apps.

Front-end layout

Page Types
basicPage
bootstrapPage
fillPage
fixedPage
fluidPage
navbarPage

Some basic objects

List of (standard) input types

Input controls p1 Input controls p2
checkboxGroupInput passwordInput
checkboxInput restoreInput
dateInput selectInput
dateRangeInput selectizeInput
fileInput sliderInput
numericInput

List of (standard) output types

Output controls p1 Output controls p2
dataTableOutput tableOutput
htmlOutput textOutput
imageOutput uiOutput
plotOutput verbatimTextOutput

Dates

shinyApp(
  ui = fluidPage(dateInput("datePicker"
                , "Pick a date:"
                , format="dd/mm/yy")),
  server = function(input, output) {}
  ,options = defaultdisplay
)

Values

Sliders

shinyApp(
  ui = fluidPage(sliderInput("vals"
              ,"Insert a number:"
              ,min=0 ,max=50 ,value=15
              ,ticks=FALSE))
  ,server = function(input, output) {}
  ,options = defaultdisplay
)

Text

Paragraph

shinyApp(
  ui = fluidPage(tags$textarea(id="charbox"
                    ,rows=3
                    ,cols=40
                    ,"Default value"))
  ,server = function(input, output) {}
  ,options = defaultdisplay
)

Selectors

shinyApp(
  ui = fluidPage(selectInput("multiselect"
              ,"Pick favourites:"
              ,c("Green","Red","Blue")
              ,multiple=TRUE))
  ,server = function(input, output) {}
  ,options = defaultdisplay
)

Text

shinyApp(
  ui = fluidPage(textInput("char", "Insert text:") ,
                 textOutput("text")  ),
  server = function(input, output) {
    output$text <- renderText(input$char)
  }  ,options = defaultdisplay
)

Let's make things short

quickShiny <- function(uFUN,sFUN,s) {
  require(shiny)
  defaultdisplay <- list(width = "100%", height = "75%")
  shinyApp(
    ui = fluidPage(uFUN("a")),
    server = function(input, output) {
      output$a <- sFUN(s)
    },options = defaultdisplay
  )
}

Interactive tables

quickShiny(uFUN = DT::dataTableOutput,
           sFUN = DT::renderDataTable,
           s    = head(iris,5))

Charts

quickShiny(uFUN = plotOutput,
           sFUN = renderPlot,
           s    = pairs(iris[,1:3]))

Some funky objects

Leaflet maps

library(leaflet)
quickShiny(uFUN = leafletOutput,
           sFUN = renderLeaflet,
           s    = leaflet() %>%  addTiles() )

Dygraphs

library(dygraphs)
quickShiny(uFUN = dygraphOutput,
           sFUN = renderDygraph,
           s    = dygraph(mdeaths))

Graphs

library(DiagrammeR)
quickShiny(uFUN = grVizOutput,
           sFUN = renderGrViz,
           s    = render_graph(create_random_graph(3,3)))

Plot.ly

library(plotly)
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:vegalite':
## 
##     add_data
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
quickShiny(uFUN = plotlyOutput,
           sFUN = renderPlotly,
           s    = plot_ly(z = volcano, type = "surface"))

Reactivity

Simple

uilist<-list(textInput("a","Text","Txt")
      ,textOutput("b"))
shinyApp(ui = fluidPage(uilist)
  ,server = function(input, output) {
    output$b <-renderText(paste0(input$a,"er"))
  },options = defaultdisplay
)

DRY

shinyApp(ui = fluidPage(uilist)
  ,server = function(input, output) {
    rand<-reactive({gen<-rpois(1,5)+1
                   paste0(gen,input$a)})
    output$b <-renderText(rand())
  },options = defaultdisplay
)

Isolated

uilist[[3]]<-actionButton("go","Go")
shinyApp(ui = fluidPage(uilist)
  ,server = function(input, output) {
    rand<-eventReactive(input$go
                  ,{gen<-rpois(1,5)+1
                   paste0(gen,input$a)})
    output$b <-renderText(rand())
  },options = defaultdisplay
)

Styling

CSS

  • Shiny outputs html so you can write CSS that works with it
  • Full list of CSS items doesn't exist, use F12 on chrome or check out selectorgadget via rvest
  • Standard classes will work

shinythemes

  • Get a different look and feel with the package shinythemes
  • Uses a number of bootstrap based themes
  • Good-looking quickly, but of course not company branded
  • View themes at bootswatch.com

shinydashboards

Infrastructure

Ad-hoc shiny

  • Rstudio (easiest) or just run directly
  • Use shiny::runApp()
  • Great for "expert" use

Cloud

  • shinyApps.io
  • Deploy with shinyApps package
  • Free for light use
  • Extra management features at increased costs
  • Great for hands-off management

Central server

  • shiny-server
  • Runs on linux
  • Free community edition
  • Extra management features & LDAP auth in Pro Edition (but can roll your own)
  • Great for sensitive and/or db-driven appplications

Wrap up

Conclusion

  • shiny is an easy framework
  • shiny is very extendable
  • shiny has a variety of deployment options

Get the code

  • Browse on github: stephlocke/Rtraining
  • Download everything:

    if (!require(devtools)) install.packages("devtools")
    devtools::install_github("stephlocke/Rtraining")

Q & A

Thank you

  • Attendees
  • Organisers and volunteers

Recommended reading

Steph Locke

The end!