DSCI 325: Handout 23 – Introduction to R Shiny
Spring 2016
Shiny is an R package that allows users to build interactive web applications using R.
Programming in Shiny is more involved than using the manipulate function, but it also offers
more flexibility and is worth the extra effort. RStudio has put together an excellent tutorial on
Shiny: http://shiny.rstudio.com/tutorial/. Much of this handout is based on this tutorial.
To begin, you’ll need to install and load the Shiny package:
> install.packages("shiny")
> library("shiny")
The Structure of a Shiny App
Shiny apps consist of two components:
A user-interface script (ui.R)
A server script (server.R)
The user-interface script defines the layout and appearance of your app. The server script, on the
other hand, contains the R code your computer needs to build your app. The code below shows the
bare minimum needed to create a Shiny app.
ui.R
shinyUI(fluidPage(
))
server.R
shinyServer(function(input, output) {
})
Running a Shiny App
To create an app, these two scripts must be saved together in a directory. In RStudio, you can
create a new app by selecting File > New File > Shiny Web App…
In the dialog box that appears, name your app and specify its directory (each app needs its own
unique directory). The dialog box shown below will create an app named “FirstApp” that will be
saved in the specified folder. Note that it is easiest to create a “multiple file” application type.
1
To create the app, save the above ui.R and server.R scripts inside the “FirstApp” folder. Then,
you can run the app by passing the name of its directory to the function runApp. In order for this to
work, the working directory in the R session must be set to the directory containing the application.
> setwd("R:/DSCI 325/Intro_to_R/R Shiny")
> runApp("FirstApp")
An alternative is to set your working directory to the application’s folder, itself. If you do this, you
should not specify the app’s name in the runApp function.
> setwd("R:/DSCI 325/Intro_to_R/R Shiny/FirstApp")
> runApp()
The result is an empty app with a blank user-interface. The app is shown by default in “normal”
mode. You can alternatively display the app in “showcase” mode, which will display the
source code in addition to the user-interface.
> setwd("R:/DSCI 325/Intro_to_R/R Shiny")
> runApp("FirstApp", display.mode="showcase")
2
Building a Basic User-Interface
The ui.R script uses the fluidPage function to create the app’s display. You can lay out the app by
placing elements in the fluidPage function. For example, let’s modify the ui.R script in our app
named “FirstApp.” Make the changes shown below and save the user-interface script.
ui.R
shinyUI(fluidPage(
titlePanel("First Shiny App"),
sidebarLayout(
sidebarPanel(“sidebar panel”),
mainPanel(“main panel”)
)
))
Now, when you re-run the app, you should see the following:
The titlePanel and sidebarLayout are the two most popular elements to add to fluidPage.
They create a basic Shiny app with a sidebar. The sidebarLayout function takes two arguments:
sidebarPanel function output
mainPanel function output
These place content in the panels of the user-interface. The sidebar is displayed with a distinct
background color and typically contains input controls. The main area typically contains outputs.
Note that you can move the sidebar panel to the right side of the interface using the optional
argument position=”right”:
ui.R
shinyUI(fluidPage(
titlePanel("First Shiny App"),
sidebarLayout(position=”right”,
sidebarPanel(“sidebar panel”),
mainPanel(“main panel”)
)
))
3
The app now appears as follows:
Options do exist to create more advanced layouts. For example, navbarPage allows you to create a
multi-page user-interface that includes a navigation bar. Or, fluidRow and column can be used to
build the layout up from a grid system.
Adding Control Widgets
Control widgets can be used to collect a value from the app’s user. When the user changes the
widget, the value changes, as well. Several pre-built widgets are available in Shiny:
Function
actionButton
checkboxGroupInput
checkboxInput
dateInput
dateRangeInput
fileInput
helpText
numericInput
radioButtons
selectInput
sliderInput
submitButton
textInput
Widget
Action Button
A group of check boxes
A single check box
A calendar to aid date selection
A pair of calendars for selecting a date range
A file upload control wizard
Help text that can be added to an input form
A field to enter numbers
A set of radio buttons
A box with choices to select from
A slider bar
A submit button
A field to enter text
You can add control widgets to your app by placing one of the above functions in either the
sidebarPanel or mainPanel functions in the ui.R file. Each widget function requires at least these
first two arguments:
a name for the widget (you will use this to access the widget’s value)
a label (this will appear with the widget in your app; note that it can be an empty string “”)
4
For example, consider the following modification to the user-interface script for “FirstApp.”
ui.R
shinyUI(fluidPage(
titlePanel("First Shiny App"),
sidebarLayout(
sidebarPanel(
sliderInput("obs",
"Number of observations:",
min=0,
max=100,
value=50)),
mainPanel("main panel")
)
))
Once these changes are made and the user-interface script is saved, we see the following when we
run the app:
Displaying Reactive Output
Shiny is built on the idea of reactive programming (outputs are automatically updated when an
input value changes). Reactive output is created with a two-step process:
1. Add an R object to your user-interface with ui.R.
2. Tell Shiny how to build the object in server.R. The object will be reactive if the code used
to build it calls a widget value.
The following functions turn R objects into output for your user-interface.
Output Function
htmlOutput
imageOutput
plotOutput
Creates…
Raw HTML
Image
Plot
5
Output Function
tableOutput
textOutput
uiOutput
verbatimTextOutput
Creates…
Table
Text
Raw HTML
text
Once again, you can add output to the user-interface by placing one of the above output functions in
either the sidebarPanel or mainPanel functions in the ui.R script.
Placing an output function in the ui.R file tells Shiny where to display your object, but you still
need to tell it how to build your object. This happens in the unnamed function that appears inside
the server.R script.
This unnamed function builds a list-like object named “output” that contains all of the code needed
to update the R objects in your app. You can create an entry by defining a new element for output
within the unnamed function (the name of this element should match the name of the reactive
element created in ui.R. For example, the following scripts together create a plot in the app’s
output.
ui.R
shinyUI(fluidPage(
titlePanel("First Shiny App"),
sidebarLayout(
sidebarPanel(
sliderInput("obs",
"Number of observations:",
min=0,
max=100,
value=50)
),
mainPanel(
plotOutput("distPlot")
)
)
))
server.R
shinyServer(function(input, output) {
output$distPlot <- ## assignment statements
})
What should the “assignment statements” mentioned in the above server.R script look like? Each
entry to output should contain the output of one of Shiny’s render functions.
6
Render Function
renderImage
renderPlot
renderPrint
renderTable
renderText
renderUI
Creates…
Images
Plots
Any printed output
Data frame, matrix, other table-like structures
Character strings
A Shiny tag object or HTML
For example, consider modifying our app to plot a histogram of 100 observations which are
randomly drawn from the normal distribution.
ui.R
shinyUI(fluidPage(
titlePanel("First Shiny App"),
sidebarLayout(
sidebarPanel(
sliderInput("obs",
"Number of observations:",
min=0,
max=100,
value=50)
),
mainPanel(
plotOutput("distPlot")
)
)
))
server.R
shinyServer(function(input, output) {
output$distPlot <- renderPlot({
dist <- rnorm(n = 100)
histogram(dist)
})
})
When the app is run, the following is displayed:
7
When the previous server.R script is submitted, the app displays the plot; however, the plot is not
yet reactive. To make it react to the slider bar, you must ask Shiny to call a widget value when it
builds the plot. This is accomplished using the input object. The current values of all widgets in
your app are saved under the names that were assigned to the widgets in the ui.R script.
ui.R
shinyUI(fluidPage(
titlePanel("First Shiny App"),
sidebarLayout(
sidebarPanel(
sliderInput("obs",
"Number of observations:",
min=0,
max=100,
value=50)
),
mainPanel(
plotOutput("distPlot")
)
)
))
server.R
shinyServer(function(input, output) {
output$distPlot <- renderPlot({
dist <- rnorm(n = input$obs)
histogram(dist)
})
})
Now, the plot will update when the slider bar is moved.
Tasks:
1. Modify the app so that you can simulate up to 1000 observations. Start your slider bar at 500.
2. Add a numeric input to change the mean and standard deviation of the normal distribution from
which the random sample is taken.
3. Add an input that allows you to simulate data from either a standard normal distribution (with
mean = 0 and standard deviation = 1) or a gamma distribution with shape parameter = 1 (you can
use the rgamma function). This app should allow you to choose the number of observations, as
well.
8
© Copyright 2026 Paperzz