Chapter 6 Creating Web Apps using Shiny
(Computer Lab 4B)
To conclude our exploration of the different data visualisation and interactive content creation options R offers, we will take a brief look at the Shiny R package (Chang et al. 2021) in Computer Lab 4B. Using this package, we can create an interactive web app, all within R.
Don’t worry, you don’t need to have any prior knowledge in other coding languages, nor a background in web development. Now that we can do some coding in R, we should be able to tackle Shiny.
We won’t be able to cover everything Shiny-related in the one lab, but we hope to provide a taste of the potential that Shiny offers.
We strongly recommend that you read through this section before starting computer lab 4B. You will also benefit from having this page open while working through the lab.
Note: We suggest finishing the previous labs before reading any further.
6.1 Shiny Introduction
Shiny is an exceptional web application framework for R, and is surprisingly easy to learn (but like most things, difficult to master). To use Shiny in R, we first have to install the shiny
R package, just like all the other R packages we have used so far.
Run the code below to install and load Shiny in R.
install.packages("shiny")
library(shiny)
6.1.1
Shiny has several built-in examples - let’s take a look at one of these now. Run the following code:
runExample("01_hello")
A new window should appear with a preview of the web app - take a look at the different elements, and try moving the slider (it should feel familiar after our work in the previous labs).
You will have noticed that by moving the slider, we are dynamically changing the number of bins used when displaying the histogram. This responsiveness is coded into the web app, using R code. Let’s take a look at the composition of this R code now.
6.2 Shiny App Code Structure
Shiny apps consist of three components:
- A user-interface object (
ui
) - A server function (
server
) - A call to the
shinyApp
function
The ui
object contains the source code which Shiny uses to prepare what the end-users of the web app see. In other words, this file controls the appearance and layout of the Shiny app. In the example Shiny web app from 6.1.1, the changes in the slider as we change the number of histogram bins are handled by the source code in the ui
object.
The server
function contains the R code which is used as a blueprint/set of instructions on how your computer should actually build your app. For example, the server
function for the 6.1.1 example Shiny web app contains the R code to produce the histogram.
In previous iterations of Shiny, these two components needed to be in separate files, but now all Shiny apps can be contained within a single script, app.R
, which makes life easier!6
Every Shiny app will have this structure: an app.R
file, containing a ui
object and a server
function.
6.2.1
Before we talk about the shinyApp
function, let’s take a look at the ui
object code for the example Shiny web app from 6.1.1:
# Define UI for app that draws a histogram ----
<- fluidPage(
ui
# App title ----
# 0
titlePanel("Hello Shiny!"),
# Sidebar layout with input and output definitions ----
# 1
sidebarLayout(
# Sidebar panel for inputs ----
# 2
sidebarPanel(
# Input: Slider for the number of bins ----
# 3
sliderInput(inputId = "bins",
label = "Number of bins:",
min = 1,
max = 50,
value = 30)
),
# Main panel for displaying outputs ----
# 4
mainPanel(
# Output: Histogram ----
# 5
plotOutput(outputId = "distPlot")
)
) )
Note we have added commented numbers (i.e. 0, 1, 2, 3, 4 and 5) to the different sections of the code.
Let’s break down these different sections, referring to each numbered section in turn.
- The
titlePanel
function allows us to specify the title of our app. - The
sidebarLayout
function specifies the appearance of the app, splitting the display into a sidebar and a main area (the sidebar is half the width of the main area by default). - The
sidebarPanel
function typically contains functions or arguments that specify the details of what goes in the sidebar section of the app. - In this example, the
sliderInput
function is used, to add a slider in the sidebar for the number of bins in the histogram (you can see that the code is specifying that between 1 and 50 bins are allowed to be chosen). - Now that we have finished specifying the layout and appearance of the sidebar, we use the
mainPanel
function to specify that we are now working on the main area of the app. - We can see that R is being told to put the
distPlot
plot in the main panel.
All of these functions are wrapped within the fluidPage
function, which we don’t need to worry about just yet.
6.2.2
What about distPlot
? Why are we using something that hasn’t been defined?
To answer this, let’s take a look now at the corrsponding server
function.
Note that once again, we have added commented numbers to the different sections of the code.
# Define server logic required to draw a histogram ----
# 1
<- function(input, output) {
server
# Histogram of the Old Faithful Geyser Data ----
# with requested number of bins
# This expression that generates a histogram is wrapped in a call
# to renderPlot to indicate that:
#
# - It is "reactive" and therefore should be automatically
# re-executed when inputs (input$bins) change
# - Its output type is a plot
# 2
$distPlot <- renderPlot({
output
# 3
<- faithful$waiting
x <- seq(min(x), max(x), length.out = input$bins + 1)
bins
# 4
hist(x, breaks = bins, col = "#75AADB", border = "white",
xlab = "Waiting time to next eruption (in mins)",
main = "Histogram of waiting times")
})
}
- In brief, the
server
function performs some calculations and produces a histogram, with a number of bins that can be modified by the end-user (with the modification options specified in theui
object above). - The output of the
renderPlot
function is assigned to the output object nameddistPlot
. - This
renderPlot
function contains some arguments which are used to specify the details used for the plot. - These details are used within the
hist
function, to produce a histogram - and the results are passed, via therenderPlot
function, to thedistPlot
object.
So, the name distPlot
was arbitrary - any name could have been chosen. The important thing is to ensure that the names we use for any output we want shown in our web app are identical across our ui
object and server
function code.
6.2.3
Once we are happy with the code for our web app, we need to create it!
The code below shows the general layout for a Shiny app. Note that we must begin by loading the shiny
package, then define our ui
object and server
function, and finally finish with using the shinyApp
function. Within the shinyApp
function, we must specify the ui
object and server
function we are pairing together to produce our app.
library(shiny)
# See the code chunks above for details on ui and server
<- ...
ui
<- ...
server
shinyApp(ui = ui, server = server)
6.3 Creating a Shiny App
To create a Shiny app, we first need to write our app.R
script, and then save it in a new directory (e.g. a new folder) within our current working directory.
For example, I could save my app.R
script to a new directory called my_data_science_shiny_app
(which is within my current working directory).
Note: If you need a refresher on changing working directories, check the code chunk below:
# Your current working directory can be checked by running the code
getwd()
# You can change your working directory using several methods - one of the easiest is:
# Navigate to the menu bar at the top of the RStudio GUI, and click
# Session -> Set Working Directory -> Choose Directory...
# and go from there
If I would now like to run this app, I can do so by using the runApp
function, as follows:
library(shiny)
runApp("my_data_science_shiny_app")
# The directory name must be enclosed within quotation marks
Note that it is good practice to have a separate directory for each of your Shiny apps.
In Computer Lab 4B, we will develop a custom Shiny app - by reading through this content first, you should now be well prepared to tackle this challenge.
6.4 Publishing a Shiny App
The easiest way to share your Shiny app with others is to simply send them your app.R
script (and associated files). However, this assumes that they have R and know how to use it.
If you would like instead to share your Shiny app as an online web page, then it can be accessed by anyone with the internet. The simplest option for this is to host your app on RStudio’s Shiny app hosting service shinyapps.io.
Note: If you are interested in doing this, make sure you select the Free option, which will allow you to host up to 5 apps free of charge.
While there are alternatives to this option, they require additional steps, and more advanced coding and IT skills which we don’t cover in this subject.
References
Note: You can still create Shiny apps with separate
ui.R
andserver.R
files, but for this subject we will focus on single-file apps.↩︎