Building Shiny Apps
Dean Attali�http://deanattali.com
@daattali
These slides are meant as a teaching aid for my Shiny tutorial:
http://deanattali.com/blog/building-shiny-apps-tutorial/
2
What is Shiny?
3
Examples
4
What is a Shiny app?
Computer running R
Web page
5
What is a Shiny app?
User interface (UI)
Server code
6
Shiny app template
library(shiny)
ui <- fluidPage()
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
7
Important: Do not place any code after shinyApp(...)
Run Shiny app in RStudio, method 1
Save file as “app.R” → “Run” button turns to “Run App”
8
Good for creating Shiny apps quickly, all code in one file
Run Shiny app in RStudio, method 2
Save UI as “ui.R” and server as “server.R” in same directory
Good for complex Shiny apps, separates view vs logic
If using this method, do not include a call to shinyApp(...)
9
Run Shiny app in RStudio, method 3
File > New File > Shiny Web App...
Generates the template for you
10
Stop Shiny app in RStudio
Press “Esc” or click the Stop icon
11
Work through the tutorial
until the end of Section 4
12
Add elements to app inside fluidPage()
fluidPage(
h1("My Shiny app"),
"Hello STAT545"
)
library(shiny)
ui <- fluidPage("Hello STAT545")
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
13
ui
Add HTML to fluidPage()
14
Add HTML to fluidPage()
ui
fluidPage(
h1("My Shiny app"),� h3("Subtitle"),
"Hello",
"STAT545",�br(),�strong("bold text")
)
15
ui
Use a layout
16
Use a layout - sidebarLayout()
fluidPage(
titlePanel("My Shiny app"),
sidebarLayout(
sidebarPanel(
"This is a side panel"
),
mainPanel(
"And this is the main stuff"
)
)
)
17
ui
Use a layout - sidebarLayout()
18
titlePanel()
mainPanel()
sidebarPanel()
Work through the tutorial
until the end of Section 5
19
Inputs and outputs
fluidPage(
# *Input() functions,
# *Output() functions
)
20
ui
Inputs
library(shiny)
ui <- fluidPage(
sliderInput(
"num", "Choose a number",
min = 0, max = 100,
value = 20)
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
21
Inputs
sliderInput("num", "Choose a number",
min = 0, max = 100, value = 20)
<div class="form-group shiny-input-container">
<label class="control-label" for="num">Choose a number</label>
<input class="js-range-slider" id="num" data-min="0" data-max="100" data-from="20" data-step="1" data-grid="true" data-grid-num="10" data-grid-snap="false" data-prettify-separator="," data-keyboard="true" data-keyboard-step="1" data-drag-interval="true" data-data-type="number"/>
</div>
22
Inputs
23
Colour input
colourpicker::colourInput()
Inputs
sliderInput("num", "Choose a number", min = 0, max = 100, value = 20)
*Input( inputId, label, ... )
?sliderInput
What arguments can I pass to an input function?
24
Input name
Label to display
Input-specific arguments
Work through the tutorial
until the end of Section 6
25
Outputs
26
Function | Outputs |
plotOutput() | plot |
tableOutput() | table |
uiOutput() | Shiny UI element |
textOutput() | text |
Outputs
plotOutput("myplot", width = "300px")
?plotOutput
What arguments can I pass to an output function?
*Output( outputId, ... )
27
Output name
Output-specific arguments
Outputs
library(shiny)
ui <- fluidPage(
sliderInput("num", "Choose a number",
0, 100, 20),
plotOutput("myplot")
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
28
*Output() adds space for UI object
You need to build the object in server
Summary
library(shiny)
ui <- fluidPage()
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
29
Begin app with template
Add elements as arguments to fluidPage()
Create inputs with *Input() functions
Create outputs with *Output() functions
Use server to assemble inputs into outputs
Two most common “why isn’t my app running?!” problems
Remember to:
30
Work through the tutorial
until the end of Section 8
31
Server: assemble input into outputs
with 3 rules
server <- function(input, output) {
output$myplot <- renderPlot({
plot(rnorm(input$num))
})
}
32
Building outputs
1 - Save objects into output$
server <- function(input, output) {
output$myplot <- renderPlot({
plot(rnorm(input$num))
})
# in UI: plotOutput("myplot")
}
33
Building outputs
2 - Build objects with render*
server <- function(input, output) {
output$myplot <- renderPlot({
plot(rnorm(input$num))
})
}
34
*Output() → render*()
35
Output function | Render function |
plotOutput() | renderPlot({}) |
tableOutput() | renderTable({}) |
uiOutput() | renderUI({}) |
textOutput() | renderText({}) |
render*() functions build reactive
output to display in UI
renderPlot({ plot(rnorm(100)) })
36
Code to build the object
Type of object to build
Building outputs
3 - Access input values with input$
server <- function(input, output) {
output$myplot <- renderPlot({
plot(rnorm(input$num))
# in UI:sliderInput("num", ...)
})
}
37
Using input$
input$num returns 25
input$num returns 50
input$num returns 75
38
Work through the tutorial
until the end of Section 9
39
Reactivity
x <- 5
y <- x + 1
x <- 10
# y is still 6
40
Reactivity
output$myplot <- renderPlot({
plot(rnorm(input$num))
})
41
Reactive contexts
42
Reactive contexts
Assign variable Access variable
server <- function(input, output) {
x <- input$num + 1
}
# error
server <- function(input, output) {
x <- reactive({
input$num + 1
})
}
# OK
server <- function(input, output) {
print(input$num)
}
# error
server <- function(input, output) {
observe({
print(input$num)
})
}
# OK
43
Simple Shiny app using basic reactivity
library(shiny)
ui <- fluidPage(
sliderInput("num", "Choose a number",
0, 100, 20),
plotOutput("myplot")
)
server <- function(input, output) {
output$myplot <- renderPlot({
plot(seq(input$num))
})
x <- reactive({
input$num + 1
})
observe({
print(x())
})
}
shinyApp(ui = ui, server = server)
Single file Two files
library(shiny)
fluidPage(
sliderInput("num", "Choose a number",
0, 100, 20),
plotOutput("myplot")
)
library(shiny)
function(input, output) {
output$myplot <- renderPlot({
plot(seq(input$num))
})
x <- reactive({
input$num + 1
})
observe({
print(x())
})
}
44
app.R
ui.R
server.R
Work through the tutorial
until the end of Section 10
45
Using buttons in the UI
ui <- fluidPage(
actionButton("btn", "Click me")
)
server <- function(input, output, session) {
observe({
cat(input$btn)
})
}
shinyApp(ui = ui, server = server)
46
Work through the tutorial
until the end of Section 12
47
Share your app: shinyapps.io
48
Work through the tutorial
until the end of Section 13
49
PS. Shiny in Rmarkdown
---
output: html_document
runtime: shiny
---
```{r echo=FALSE}
sliderInput("num", "Choose a number",
0, 100, 20)
renderPlot({
plot(seq(input$num))
})
```
50
PPS. More things to check out
51
Recommended add-on packages to Shiny
52
Awesome non-intimidating resources
53