Zhiguang Huo (Caleb)
Monday September 26, 2022
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/Desktop") ## change to your path
runApp("test", display.mode = "showcase")
save the code as ui.R and server.R
setwd("/Users/zhuo/Desktop") ## change to your path
runApp("test", 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
Sign in and setup your account
install.packages('rsconnect')
rsconnect::setAccountInfo
rsconnect::deployApp('path/to/your/app') ## setup account if you have multiple accounts
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(
They are identical but for one thing:
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/2022FALL/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)