15 Nov 2024
Shiny is a “framework for creating web applications using R code”
You can create a dashboard or an interactive map without knowing anything about HTML, CSS, or JavaScript
You’ll learn the two key components of every Shiny app: the UI (user interface) which defines how your app looks, and the server function which defines how your app works
Shiny uses reactive programming to automatically update outputs when inputs change so we’ll finish off the chapter by learning the third important component of Shiny apps: reactive expressions
You first need to install install.packages("shiny")
Then load in your current R session library(shiny)
app.R
fileCreate a new directory for your app, and put a single file called app.R
in it
This app.R
file will be used to tell Shiny both how your app should look, and how it should behave
If you’re creating a complex app, you can achieve the same goal with two files: ui.R
and server.R
.
app.R
fileCreate a new directory and an app.R
file containing a basic app in one step by clicking File | New Project, then selecting New Directory and Shiny Web Application
It is very important that the name of the file is app.R
and out in its own folder, otherwise it would not be recognised as a Shiny app
There are a few ways you can run this app:
Click the Run App
button in the document toolbar
Use a keyboard shortcut: Cmd/Ctrl + Shift + Enter
Deploy to the shinyapps.io cloud
fluidPage()
to render textReplace the line in your app that assigns an empty fluidPage()
into ui with the one above, and run the app
The entire UI will be built by passing comma-separated arguments into the fluidPage()
function. By passing regular text, the webpage will just render boring unformatted text
If you want your text to be formatted nicer, Shiny has many functions that are wrappers around HTML tags that format text
h1() function for a top-level header
h2() for a secondary header
strong() to make text bold
em() to make text italicised
and many others
You could add a title to the app with either h1()
or Shiny also has a special function titlePanel()
Using titlePanel()
adds a visible big title-like text to the top of the page
sidebarLayout()
to add a simple structure. It provides a simple two-column layout with a smaller sidebar and a larger main panel
You can add the following code after the titlePanel()
fluidPage()
need to be separated by commasInputs are what gives users a way to interact with a Shiny app. Shiny provides many input functions to support many kinds of interactions that the user could have with an app
textInput()
is used to let the user enter text, numericInput()
lets the user select a number, dateInput()
is for selecting a date, and selectInput()
is for creating a select box (i.e. dropdown menu)
All input functions have the same first two arguments: inputId
and label
. The inputId
will be the name that Shiny will use to refer to this input when you want to retrieve its current value
The label
argument specifies the text in the display label that goes along with the input widget
The first input we can have is to select a country in this data
The most appropriate input type in this case is probably the select box. Look at the documentation for selectInput()
and create an input function
selectInput(
inputId = "variable",
label = "Select variable",
choices = c("Deaths", "Injuries", "Homelessness"),
selected = "Deaths"
)
sidebarPanel()
, after the previous input (separate them with a comma)The most sensible type of input for this is sliderInput()
Looking at the documentation for sliderInput()
, you’ll see that by supplying a vector of length two as the value argument, it can be used to specify a range rather than a single number
After creating all the inputs, we should add elements to the UI to display the outputs. Outputs can be any object that R creates and that we want to display in our app - such as a plot, a table, or text
Shiny provides several output functions, one for each type of output. Similarly to the input functions, all the output functions have a outputId
argument that is used to identify each output, and this argument must be unique for each output
Since we want a plot to show trends of disaster statistics, the function we can use is plotOutput()
You can add the following code into the mainPanel()
Since we want a plot to show trends of disaster statistics, the function we can use is tableOutput()
You can add the following code into the mainPanel()
If you look at the server function, you’ll notice that it is always defined with two arguments: input and output
You must define these two arguments! Both input and output are list-like objects. As the names suggest, input is a list you will read values from and output is a list you will write values to
input
will contain the values of all the different inputs at any given time, and output
is where you will save output objects (such as tables and plots) to display in your app
Save the output
object into the output list (remember the app template - every server function has an output argument)
Build the object with a render
* function, where * is the type of output
Access input
values using the input list (every server function has an input argument)
Let’s learn how to make an output depended on an input
The variable input
contains a list of all the inputs that are defined in the UI
input$year_range
return a vector of length two containing the minimum and maximum year. Whenever the user manipulates the slider in the app, these values are updated, and whatever code relies on it gets re-evaluated. This is a concept known as reactivity
server <- function(input, output, session) {
output$plot <- renderPlot({
variable <- switch(input$variable,
"Deaths" = "deaths",
"Injuries" = "injuries",
"Homelessness" = "homelessness")
data %>%
filter(country == input$country,
Year >= input$year_range[1],
Year <= input$year_range[2]) %>%
ggplot(aes(Year, .data[[variable]])) +
geom_line() +
labs(y = input$variable)
})
}
server <- function(input, output, session) {
output$plot <- renderPlot({ variable <- switch(input$variable, "Deaths"
= "deaths", "Injuries" = "injuries", "Homelessness" = "homelessness")
data %>%
filter(country == input$country,
Year >= input$year_range[1],
Year <= input$year_range[2]) %>%
ggplot(aes(Year, .data[[variable]])) +
geom_line() +
labs(y = input$variable)
})
}
if (!require(shiny)) install.packages("shiny")
if (!require(ggplot2)) install.packages("ggplot2")
if (!require(dplyr)) install.packages("dplyr")
library(shiny)
library(ggplot2)
library(dplyr)
# Read data from CSV
data <- read.csv("emdat_app.csv")
ui <- fluidPage(
# Header
h1("Disaster statistics trends"),
# Sidebar layout
sidebarLayout(
# Sidebar panel
sidebarPanel(
selectInput(
inputId = "country",
label = "Select country",
choices = unique(data$country),
selected = "Belgium"
),
selectInput(
inputId = "variable",
label = "Select variable",
choices = c("Deaths", "Injuries", "Homelessness"),
selected = "Deaths"
),
sliderInput(
inputId = "year_range",
label = "Select year range",
min = min(data$Year),
max = max(data$Year),
value = c(min(data$Year), max(data$Year)),
step = 1,
sep = ""
)
),
# Main panel
mainPanel(
plotOutput("plot")
)
)
)
server <- function(input, output, session) {
output$plot <- renderPlot({
variable <- switch(input$variable,
"Deaths" = "deaths",
"Injuries" = "injuries",
"Homelessness" = "homelessness")
data %>%
filter(country == input$country,
Year >= input$year_range[1],
Year <= input$year_range[2]) %>%
ggplot(aes(Year, .data[[variable]])) +
geom_line() +
labs(y = input$variable)
})
}
shinyApp(ui, server)
Further texts:
Tutorials:
Problem 1: Setup
Initialise a Shiny app and load required libraries
Read “emdat_app.csv” into data
Problem 2: UI Design
Problem 3: Initial Plot
Display a placeholder plot
Filter data based on user inputs and create a line plot
Problem 4: Plot Customisation
Label axes dynamically based on the selected variable
Implement UI option for different plot types
Problem 5: Dynamic Updates
Use reactive expressions to update variable choices based on the selected country
Make the plot dynamically update with user inputs
Problem 6: Testing and Debugging
SOCS0100 – Computational Social Science