Zhiguang Huo (Caleb)
Monday September 20, 2021
Credits to these resources:
The Training Materials are licensed under the Creative Commons Attribution-Noncommercial 3.0 United States License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc/3.0/us/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
We will see two key components:
library(shiny)
ui <- fluidPage()
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
ui <- fluidPage("Hello World!")
ui <- fluidPage(
# *Input() functions,
# *Output() functions
)
# library(shiny)
ui <- fluidPage(
  sliderInput(inputId = "num",
              label = "Choose a number",
              value = 25, min = 1, max = 100)
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
Try each one of these components
# library(shiny)
ui <- fluidPage(
  sliderInput(inputId = "num",label = "Choose a number",value = 25, min = 1, max = 100),
  actionButton(inputId = "actionButton",label="Action"),
  submitButton(text = "Submit"),
  checkboxInput(inputId = "checkbox", label = "Choice A"),
  checkboxGroupInput(inputId = "checkboxgroup", label = "Checkbox group", choices = c("A"="Choice 1", "B"="Choice 2")),
  dateInput(inputId = "dateInput", label = "date input", value = "2021-09-20"),
  fileInput(inputId = "fileInput", label = "File input"),
  numericInput(inputId = "numericInput", label = "Numeric input", value = "10"),
  textInput(inputId = "textInput", label = "Text input", value = "Enter text..."),
  radioButtons(inputId = "radioButton", label = "Radio buttons", choices = c("A"="Choice 1", "B"="Choice 2")),
  selectInput(inputId = "selectBox", label = "Select box", choices = c("A"="Choice 1", "B"="Choice 2"))
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
Also see: https://shiny.rstudio.com/gallery/widget-gallery.html
To display output, add an Output() function to the fluidPage(), separated by “,”
# library(shiny)
ui <- fluidPage(
  sliderInput(inputId = "num",
              label = "Choose a number",
              value = 25, min = 1, max = 100),
  plotOutput(outputId="hist")
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
In this example,
ui <- fluidPage(
  sliderInput(inputId = "num",label = "Choose a number",
              value = 25, min = 1, max = 100),
  plotOutput(outputId="hist")
)
server <- function(input, output) {
  output$hist <- renderPlot({
    hist(rnorm(100))
  })}
shinyApp(ui = ui, server = server)
Example 0
ui <- fluidPage(
  sliderInput(inputId = "num",label = "Choose a number",
              value = 25, min = 1, max = 100),
  plotOutput(outputId="hist")
)
server <- function(input, output) {
  output$hist <- renderPlot({
    hist(rnorm(input$num))
  })
}
shinyApp(ui = ui, server = server)
input argument in server matches inputID in ui
Output will automatically update if you follow the 3 rules
Every Shiny app is maintained by a computer running R
local laptop 
remote server 
setwd("/Users/zhuo/Dropbox/teaching/2021FALL/lectures/Week5_RShiny/RShiny/example") ## change to your path
runApp("toy", display.mode = "showcase")
save the code as ui.R and server.R
setwd("/Users/zhuo/Dropbox/teaching/2021FALL/lectures/Week5_RShiny/RShiny/example") ## change to your path
runApp("toy2", display.mode = "showcase")
mode:
There are many servers. - Shinyapps.io is a server maintained by R studio. - Free for basic usage.
Reference: https://shiny.rstudio.com/articles/shinyapps.html
install.packages('rsconnect')
rsconnect::setAccountInfo
rsconnect::deployApp('path/to/your/app')
server <- function(input, output) {
  output$hist <- renderPlot({ hist(rnorm(100, input$num)) })
}
server <- function(input, output) {
  output$hist <- hist(rnorm(input$num)) ## this won't work
}
Reactive values notify the Reactive functions when they become invalid. This happens when you update your input values.
The Reactive functions refresh. This will update the output result.
Reactive functions:
ui <- fluidPage(
  sliderInput(inputId = "num",
              label = "Choose a number",
              value = 25, min = 1, max = 100),
  textInput(inputId = "title",
            label = "Write a title",
            value = "Histogram of Random Normal Values"),
  plotOutput("hist")
)
server <- function(input, output) {
  output$hist <- renderPlot({
          hist(rnorm(input$num), main = input$title)
  })
}
shinyApp(ui = ui, server = server)
When notified that the reactive function is invalid, the object created by a render*() function will rerun the entire block of code associated with it.
ui <- fluidPage(
  sliderInput(inputId = "num",
              label = "Choose a number",
              value = 25, min = 1, max = 100),
  plotOutput("hist"),
  verbatimTextOutput("stats")
)
server <- function(input, output) {
  output$hist <- renderPlot({
    hist(rnorm(input$num))
  })
  output$stats <- renderPrint({
    summary(rnorm(input$num))
  })
}
shinyApp(ui = ui, server = server)
Problem: input$num for hist and stats are not the same.
reactive() function builds a reactive object - will make sure the same input for all downstream functions
data <- reactive( {rnorm(input$num)})
ui <- fluidPage(
  sliderInput(inputId = "num",
              label = "Choose a number",
              value = 25, min = 1, max = 100),
  plotOutput("hist"),
  verbatimTextOutput("stats")
)
server <- function(input, output) {
  data <- reactive({
    rnorm(input$num)
  })
  output$hist <- renderPlot({
    hist(data())
  })
  output$stats <- renderPrint({
    summary(data())
  })
}
shinyApp(ui = ui, server = server)
isolate({rnorm(input$num)})
ui <- fluidPage(
  sliderInput(inputId = "num",
              label = "Choose a number",
              value = 25, min = 1, max = 100),
  textInput(inputId = "title",
            label = "Write a title",
            value = "Histogram of Random Normal Values"),
  plotOutput("hist")
)
server <- function(input, output) {
  output$hist <- renderPlot({
    hist(rnorm(input$num),
         main = isolate({input$title}))
  })
}
shinyApp(ui = ui, server = server)
Example 5, actionButton
library(shiny)
ui <- fluidPage(
  actionButton(inputId = "clicks",
               label = "Click me")
)
server <- function(input, output) {
  observeEvent(input$clicks, {
    print(as.numeric(input$clicks))
  })
}
shinyApp(ui = ui, server = server)
Example 6, eventReactive()
ui <- fluidPage(
  sliderInput(inputId = "num",
              label = "Choose a number",
              value = 25, min = 1, max = 100),
  actionButton(inputId = "go",
               label = "Update"),
  plotOutput("hist")
)
server <- function(input, output) {
  data <- eventReactive(input$go, {
    rnorm(input$num)
  })
  output$hist <- renderPlot({
    hist(data())
  })
}
shinyApp(
Example 7 – reactiveValues()
ui <- fluidPage(
  actionButton(inputId = "norm", label = "Normal"),
  actionButton(inputId = "unif", label = "Uniform"),
  plotOutput("hist")
)
server <- function(input, output) {
  rv <- reactiveValues()
  rv$data <- rnorm(100)
  observeEvent(input$norm, { rv$data <- rnorm(100) })
  observeEvent(input$unif, { rv$data <- runif(100) })
  output$hist <- renderPlot({
    hist(rv$data)
  })
}
shinyApp(ui = ui, server = server)
The R Shiny UI was built by HTML, try the following in R console:
ui <- fluidPage()
ui
sliderInput(inputId = "num",
  label = "Choose a number",
  value = 25, min = 1, max = 100)
plotOutput("hist")
<div class="container-fluid">
  <h1>My Shiny App</h1>
  <p style="font-family:Impact">
    See other apps in the
    <a href="http://www.rstudio.com/products/shiny/shiny-usershowcase/">
    Shiny Showcase</a>
  </p>
</div>
Save it to a html file, and open it.
When writing HTML, add content with tags:
<h1></h1>
<a></a>
When writing R, add content with tag functions
##   [1] "a"                   "abbr"                "address"            
##   [4] "animate"             "animateMotion"       "animateTransform"   
##   [7] "area"                "article"             "aside"              
##  [10] "audio"               "b"                   "base"               
##  [13] "bdi"                 "bdo"                 "blockquote"         
##  [16] "body"                "br"                  "button"             
##  [19] "canvas"              "caption"             "circle"             
##  [22] "cite"                "clipPath"            "code"               
##  [25] "col"                 "colgroup"            "color-profile"      
##  [28] "command"             "data"                "datalist"           
##  [31] "dd"                  "defs"                "del"                
##  [34] "desc"                "details"             "dfn"                
##  [37] "dialog"              "discard"             "div"                
##  [40] "dl"                  "dt"                  "ellipse"            
##  [43] "em"                  "embed"               "eventsource"        
##  [46] "feBlend"             "feColorMatrix"       "feComponentTransfer"
##  [49] "feComposite"         "feConvolveMatrix"    "feDiffuseLighting"  
##  [52] "feDisplacementMap"   "feDistantLight"      "feDropShadow"       
##  [55] "feFlood"             "feFuncA"             "feFuncB"            
##  [58] "feFuncG"             "feFuncR"             "feGaussianBlur"     
##  [61] "feImage"             "feMerge"             "feMergeNode"        
##  [64] "feMorphology"        "feOffset"            "fePointLight"       
##  [67] "feSpecularLighting"  "feSpotLight"         "feTile"             
##  [70] "feTurbulence"        "fieldset"            "figcaption"         
##  [73] "figure"              "filter"              "footer"             
##  [76] "foreignObject"       "form"                "g"                  
##  [79] "h1"                  "h2"                  "h3"                 
##  [82] "h4"                  "h5"                  "h6"                 
##  [85] "hatch"               "hatchpath"           "head"               
##  [88] "header"              "hgroup"              "hr"                 
##  [91] "html"                "i"                   "iframe"             
##  [94] "image"               "img"                 "input"              
##  [97] "ins"                 "kbd"                 "keygen"             
## [100] "label"               "legend"              "li"                 
## [103] "line"                "linearGradient"      "link"               
## [106] "main"                "map"                 "mark"               
## [109] "marker"              "mask"                "menu"               
## [112] "meta"                "metadata"            "meter"              
## [115] "mpath"               "nav"                 "noscript"           
## [118] "object"              "ol"                  "optgroup"           
## [121] "option"              "output"              "p"                  
## [124] "param"               "path"                "pattern"            
## [127] "picture"             "polygon"             "polyline"           
## [130] "pre"                 "progress"            "q"                  
## [133] "radialGradient"      "rb"                  "rect"               
## [136] "rp"                  "rt"                  "rtc"                
## [139] "ruby"                "s"                   "samp"               
## [142] "script"              "section"             "select"             
## [145] "set"                 "slot"                "small"              
## [148] "solidcolor"          "source"              "span"               
## [151] "stop"                "strong"              "style"              
## [154] "sub"                 "summary"             "sup"                
## [157] "svg"                 "switch"              "symbol"             
## [160] "table"               "tbody"               "td"                 
## [163] "template"            "text"                "textarea"           
## [166] "textPath"            "tfoot"               "th"                 
## [169] "thead"               "time"                "title"              
## [172] "tr"                  "track"               "tspan"              
## [175] "u"                   "ul"                  "use"                
## [178] "var"                 "video"               "view"               
## [181] "wbr"
tags$h1
tags$h1()
tags$h1("this is a header")
tags$a(href = "www.rstudio.com", "RStudio")
ui <- fluidPage(
  tags$h1("this is a header"), 
  tags$a(href = "www.rstudio.com", "RStudio")
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
ui <- fluidPage(
  tags$h1("First level"),
  tags$h2("Second level"),
  tags$h3("Third level"),
  tags$h4("Fourth level"),
  tags$h5("Fifth level"),
  tags$h6("Sixth level")
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
ui <- fluidPage(
 "This is a Shiny app.",
  "It is also a web page."
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
ui <- fluidPage(
  tags$p("This is a Shiny app."),
  tags$p("It is also a web page.")
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
ui <- fluidPage(
 tags$em("This is a Shiny app."), 
 tags$br(),
 tags$strong("This is a Shiny app."),
 tags$hr(),
 tags$code("This is a Shiny app."), 
 tags$p("This is a", tags$strong("Shiny"), "app."),
 tags$img(height=100, width=100, src="https://caleb-huo.github.io/teaching/2021FALL/logo.png")
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
To add images from local files, save the file in a subdirectory named - www
Use HTML() to pass a character string as raw HTML
ui <- fluidPage(
 HTML("<h1>My Shiny App</h1>")
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
More reference on HTML UI: shiny.rstudio.com/articles/html-ui.html
ui <- fluidPage(
  fluidRow(
    column(3),
    column(5, 
           sliderInput(inputId = "num",label = "Choose a number",
                       value = 25, min = 1, max = 100)
    )
  ),
  fluidRow(
    column(4, offset = 8,
           plotOutput(outputId="hist")
    )
  )
)
server <- function(input, output) {
  output$hist <- renderPlot({
    hist(rnorm(input$num))
  })
}
shinyApp(ui = ui, server = server)
Panels to group multiple elements into a single unit with its own properties.
ui <- fluidPage(
  #wellPanel(
  sliderInput(inputId = "num",label = "Choose a number",
              value = 25, min = 1, max = 100),
  textInput("title", value = "Histogram", label = "Write a title"),
  #)
  plotOutput(outputId="hist")
)
server <- function(input, output) {
  output$hist <- renderPlot({
          hist(rnorm(input$num), main = input$title)
  })
}
shinyApp(ui = ui, server = server)
ui <- fluidPage(
  tabsetPanel(
    tabPanel("tab 1", "contents"),
    tabPanel("tab 2", "contents"),
    tabPanel("tab 3", "contents")
    )
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
ui <- fluidPage(
  navlistPanel(
    tabPanel("tab 1", "contents"),
    tabPanel("tab 2", "contents"),
    tabPanel("tab 3", "contents")
    )
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
More reference about layout: https://shiny.rstudio.com/articles/layout-guide.html
ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(),
    mainPanel()
  )
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      sliderInput(inputId = "num",label = "Choose a number",
                  value = 25, min = 1, max = 100),
      textInput("title", value = "Histogram", label = "Write a title")
    ),
    mainPanel(
      plotOutput(outputId="hist")
    )
  )
)
server <- function(input, output) {
  output$hist <- renderPlot({
    hist(rnorm(input$num), main = input$title)
  })
}
shinyApp(ui = ui, server = server)
ui <- navbarPage( title = "Title",
            tabPanel("tab 1", "contents"),
            tabPanel("tab 2", "contents"),
            tabPanel("tab 3", "contents")
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
ui <- navbarPage(title = "Title",
          tabPanel("tab 1", "contents"),
          tabPanel("tab 2", "contents"),
          navbarMenu(title = "More",
                tabPanel("tab 3", "contents"),
                tabPanel("tab 4", "contents"),
                tabPanel("tab 5", "contents")
          )
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
dashboardPage() comes in the shinydashboard package
library(shinydashboard)
ui <- dashboardPage(
          dashboardHeader(),
          dashboardSidebar(),
          dashboardBody()
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)