Skip to content

Latest commit

 

History

History
472 lines (353 loc) · 12.8 KB

rShiny.md

File metadata and controls

472 lines (353 loc) · 12.8 KB

R Shiny Tutorial Notebook

RStudio Tutorial

Tutorial slides

Every Shiny app is maintained by a computer running R.

User interface (UI), server instructions are two required components.

Shiny App Template

The minimal code for a Shiny app.

library(shiny)
ui <- fluidPage("My Shiny App")

server <- function(input, output) {}

shinyApp(ui = ui, server = server)

Three types of functions: input, output and server.

library(shiny)
ui <- fluidPage("My Shiny App"
  # *Input() functions
  # *Output() functions
)

server <- function(input, output) {
  # server functions
}

shinyApp(ui = ui, server = server)

Shiny Input Functions

Add elements to your app as arguments to fluidPage().

library(shiny)
ui <- fluidPage("My Shiny App"
  # *Input() functions
  sliderInput(inputId = "num",
              label = "Choose a number",
              value = 25, min = 1, max = 100)
  # *Output() functions
  )

server <- function(input, output) {}

shinyApp(ui = ui, server = server)

Shiny Output Functions

To display reactive results, add to fluidPage() with an *Output() function.

library(shiny)
ui <- fluidPage("My Shiny App"
  # *Input() functions
  sliderInput(inputId = "num",
              label = "Choose a number",
              value = 25, min = 1, max = 100) # Add commas 
                                               # between
                                               # arguments
  # *Output() functions
  plotOutput("hist")                           # Adds a space 
                                               # in ui for R object.
                                               # Build object
                                               # in server func.
  )

server <- function(input, output) {}

shinyApp(ui = ui, server = server)

Server Functions

Rules to writing server functions:

  • Save objects to display to output$
    • output$foo is referenced in plotOutput("foo")
  • Build objects to display with render*()
  • Access input values with input$

library(shiny)
ui <- fluidPage(
  titlePanel("My Shiny App"),
  sidebarLayout(                                   # Add side panel for inputs
    sidebarPanel(
                                                   # *Input() functions
      sliderInput(inputId = "num",
                  label = "Choose a number",
                  value = 25, min = 1, max = 100)
    ),
    mainPanel(
                                                   # *Output() functions
      plotOutput(outputId = "hist")                # Adds an output space 
                                                   # in ui for R object.
                                                   # Build object
                                                   # in server func.
    )
  )
)

server <- function(input, output) { 
  output$hist <- renderPlot({                  # Can add R scripts and code between render {}
    title <- "100 Random Normal Values"
    hist(rnorm(input$num), main = title)       # Code that builds obj.
                                               # input$num from sliderInput in UI, num-num, :)
                                               # num-num causes automatic reativity!
  })                                           # Save object to output$
                                               # Referenced in plotOutput("")
}

shinyApp(ui = ui, server = server)

How To Save Your App

One directory with every file the app needs:

  • app.R (your script which ends with a call to shinyApp())
  • datasets, images, css, helper scripts, etc. Note- you must use exact name, app.R.

Deploy to shinyapps.io

http://shiny.rstudio.com/articles/shinyapps.html

# Install rsconnect package
if (!require("devtools"))
  install.packages("devtools")
devtools::install_github("rstudio/rsconnect")

# Set up your shinyapps.io account to recognize your computer
rsconnect::setAccountInfo(name='jefflong',
			  token='57EB65311F1075B42840A7E9AF80368B',
			  secret='<secret>')

# When ready to deploy app, point rsconnect to the app dir
library(rsconnect)
rsconnect::deployApp('/Users/jeffreylong/R/shiny/tutorialApp/shinyTutorial')

https://jefflong.shinyapps.io/shinytutorial/

Reactivity

Build reactive output to display in UI with render*(). E.g.

renderPlot(   { hist(rnorm(input$numNum)) })

When notified that it is invalid, the object created by a render*() function will rerun the entire block of code associated with it.

library(shiny)
ui <- fluidPage(
    #titlePanel(title=div(img(src="https://upload.wikimedia.org/wikipedia/commons/f/f5/Hoffmann-La_Roche_logo.svg", align="right"), "Jeff Long's Reactive Shiny App")),
    #titlePanel(title=div(img(src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/17/Roche_Logo.svg/64px-Roche_Logo.svg.png", align="right"), "Jeff Long's Reactive Shiny App")),
    titlePanel(title=div(img(src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/17/Roche_Logo.svg/128px-Roche_Logo.svg.png", align="right"), "Jeff Long's Reactive Shiny App")),
    #titlePanel(title=div(img(src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/17/Roche_Logo.svg/256px-Roche_Logo.svg.png", align="right"), "Jeff Long's Reactive Shiny App")),
  sidebarLayout(                                   # Add side panel for inputs
    sidebarPanel(
                                                   # *Input() functions
      sliderInput(inputId = "numNum",              # Input value of Slider
                  label = "Choose a number",
                  value = 25, min = 1, max = 100),
     br(),
      textInput(inputId = "note",
                label = "Note",
                value = "Histogram with statistics"),
      actionButton(inputId = "addButton", 
                   label = "Add Note")
    ),
    mainPanel(                                     # *Output() functions
      verbatimTextOutput(outputId = "stats"),
      verbatimTextOutput(outputId = "note"),
      plotOutput(outputId = "hist")                # Adds an output space 
                                                   # in ui for R object.
                                                   # Build object
                                                   # in server func.
    )
  )
)

server <- function(input, output) { 
  data <- reactive({                           # To sync data across multiple
    rnorm(input$numNum)                        # outputs. data is a function and
  })                                           # must be referred to as data()
  output$stats <- renderPrint({
    summary(data())
  })
  output$note <- renderText({
    input$addButton
    paste0("Note: ", isolate({input$note}))
  })
  output$hist <- renderPlot({                  # Reactive function handles reactive
                                               # value from *Input() function.
    title <- paste(input$numNum,               # Can add R scripts and 
             " Random Normal Values")          # code between render {}
    hist(data(), main = title)                 # Code that builds obj.
                                               # input$num from sliderInput 
                                               # in UI, num-num, :)
                                               # num-num causes automatic reativity!
  })                                           # Save object to output$
}                                              # Referenced in plotOutput("")
shinyApp(ui = ui, server = server)

An image of the Shiny app.

HTML in R

Use tags() to add static content to your Shiny app.

library(shiny)
names(tags)

Make a "www" directory, deposit images, no need to reference dir in call.

library(shiny)
ui <- fluidPage(
  wellPanel(
  tags$a(href = "https://github.com/jeffreyCarlLong/platinum-dragon/blob/master/README.md", "R Shiny Tutorial Notebook"),
  tags$h3("HTML in R"),
  tags$code("ls -la ~/*"), br(), br(),
  "Text in fluidPage will also print in the Shiny App", br(), br(),
  tags$hr(),
  tags$p("Will split content..."),
  tags$p("into separate paragraphs, with ",
         tags$strong("nested"),
         " tags.")
  )
)
server <- function(input, output) {}

shinyApp(ui = ui, server = server)

Output from above code looks like this:

Combine tabPanel() with tabsetPanel(), navlistPanel(), or navbarPage().

Add horizonal block of space with fluidRow() and blocks within with column().

The first argument to column() is the width in 12 unit increments.

Offsets from the right can also be used.

library(shiny)
fluidPage(
  tabsetPanel(
    tabPanel("Shiny App Tab 1",
    tags$img(height = 100, width = 100, src = "https://upload.wikimedia.org/wikipedia/commons/f/f5/Hoffmann-La_Roche_logo.svg"),
    fluidRow(                                  # <div class="row"> In the row</div>
      column(3), 
      column(2),                               # or column(2, plotOutput("hist")),
      column(5)                                # or column(5, sliderInput(...))
    ),
    HTML("<h4>My Roche Shiny App</h4>")
    ),
    fluidRow(
      column(4, offset=8)
    )
  )

)

Output from above code looks like this:

R wrapper functions exist for: a(), br(), code(), em(), h1(), h2(), ..., h(6), hr(), img(), p(), and strong().

library(shiny)
ui <- fluidPage(
  navbarPage(
    navbarMenu()
  )
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)

http://rstudio.github.io/shinydashboard/

CSS

https://bootswatch.com/cerulean/

<head>
  <link type="text/css" rel="stylesheet" href="bootswatch-cerulean.css"/>
  <style>
    li {
      color:purple;
    }

    .blue-item {
      color:blue;
    }

    
    #dark {
      color:navy;
    }
  </style>
</head>
 
<div>
  
<div class="container-fluid">
  <h1>CSS examples</h1>
  <p>This webpage uses...
  </p>
  <ol>
    <li> Purple line item</li>
    <li class="blue-item"> Blue item, class style over-rides global li style. </li>
    <li id="dark" class="blue-item"> Navy item, id over-rides class style. </li>
    <li id="dark" class="blue-item" style="color:green"> Green item, specify style to rule them all. </li>
  </ol>
</div>

Output from above code looks like this:

Place .css files in the www folder of your app dir. To get the CSS to be used by Shiny, try one of the following.

library(shiny)
ui <- fluidPage(
  theme = "bootswatch-cerulean.css",
  sidebarLayout(
    sidebarPanel("This is the ", strong("sidebarPanel"), " for theme bootswatch-cerulean"),
    mainPanel("This is the ", strong("mainPanel"), " for theme bootswatch-cerulean")
  )
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)

Output from above code looks like this:

library(shiny)
ui <- fluidPage(
  tag$head(
    tags$link(
      rel = "stylesheet",
      type = "text/css",
      href = "bootswatchLitera.css"
    )
  )
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)

Add global style to header for paragraph tags (p).

library(shiny)
ui <- fluidPage(
  tags$head(
    tags$style(HTML("
      p {
        color:red;
      }
    "))
  ),
  tags$p("This is some red style in Shiny.")
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)

Output from above code looks like this:

library(shiny)
ui <- fluidPage(
  includeCSS("file.css")    # Can be in app dir, not necessarily www
)

# where file.css is
HTML(             # HTML() is not in the file.css 
<style>
   p {
     color:red;
   }
</style>
)
# OR

ui <- fluidPage(
  tags$h1("Title", style = "color:red;")
)

HTML class at Code Academy, http://www.codeacademy.com/tracks/web

Shiny CSS article, http://shiny.rstudio.com/articles/css.html.

jQuery addition in the header, http://shiny.rstudio.com/articles/google-analytics.html.