(7) Dashboarding, Part I
— LAST YEAR’S CONTENT BELOW —
26.26 Orientation
26.26.1 Objective
This tutorial is intended to introduce shiny
in a classroom setting. This tutorial is intended to provide students a foundation in shiny, with the expectation that students will be able to:
- develop basic shiny apps from scratch,
- deploy a shiny app,
- create interactive Shiny R Markdown documents, and
- research more advanced shiny techniques.
26.26.2 Resources
This tutorial is an abridged version of the stat545.com shiny tutorial written by Dean Attali, with some minor differences/rearrangements. (I think) the stat545.com tutorial is identical to the tutorial on Dean’s website.
The official shiny
site is also very useful. It has tutorials, a gallery, and other goodies.
Specific topics:
- For Shiny R Markdown documents, see Chapter 19 of Yihui’s R Markdown book.
- For deploying shiny apps, see shinyapps.io.
26.26.3 Participation
We’ll be making an external product, like last week. This week we’ll be making a shiny app out of the BC liquor data (loaded in later).
Complete version by Dean Attali here.
26.27 Why use shiny
?
- When presenting your analysis: respond to others’ “what if”s.
- Both in-person meetings and written analyses.
- “There’s an app for that”, and you can make it with shiny.
- Could even provide a user interface to your R package.
- Could even make a website out of shiny, like this New Zealand Tourism website.
26.28 Getting Started with shiny
26.28.1 Together:
Install shiny, and load it:
install.packages("shiny")
library(shiny)
Start a new shiny app. “File -> New File -> shiny web app -> Single file”. Notice:
app.R
is made in a new folder.- Shiny app needs ui and server.
- Run with
shinyApp(ui, server)
– or, click “Run App” (appears ifserver
andshinyApp()
are present)
Delete the “guts” of ui and server.
26.29 Intro to the UI
26.29.1 HTML: Aside
Did you know webpages are made up of HTML? Find the “view source” button on your browser!
26.29.2 HTML: My Turn
- Character entries in
ui
displayed as-is. - Can add HTML. I’ll add a level-1 header in three ways:
tags
object- Some of the
tags
are available as functions, too, likeh1()
. HTML()
function for generic HTML.
- You can nest tags, too:
h1(em("This is my header."))
- Code before the
ui
gets run, too, and can be read by the ui. Let’s see!
26.29.3 HTML: Your Turn
Try using three tags
in the ui
, aside from h1
and em
. Find the documentation for them here (links to official shiny site).
26.29.4 Download the data: Together
Dean Attali has prepared a tidy data set as a .csv
here.
- Save this csv to your app’s folder as
bcl-data.csv
. - Read the file in by placing this code below the loading of
shiny
:
bcl <- read.csv("bcl-data.csv", stringsAsFactors = FALSE)
Explore the data.
We’ll use this later.
26.29.5 Layouts: Together
We usually place content in panels, arranged in layouts.
Most common:
sidebarLayout()
. Requires two arguments:sidebarPanel()
(column, 1/6 of the page)mainPanel()
(column, 5/6 of the page)
- Grid layout with
fluidRow()
andcolumn()
(this is more generic; provides more control)
To the ui
, let’s copy the below code, which
- gives the app a title with
titlePanel()
, and - gives the app a sidebarlayout.
titlePanel("BC Liquor price app",
windowTitle = "BCL app"),
sidebarLayout(
sidebarPanel("This text is in the sidebar."),
mainPanel("This text is in the main panel.")
)
Want more info on layouts? See shiny.rstudio.com’s layouts page.
26.29.6 Overall look at the ui
: My Turn
Check out the ui
object after running it. It’s just HTML!
26.30 Intro to the server
26.30.1 Displaying output: My Turn
Try to display a plot in the ui – a histogram of price, with ggplot2::qplot(bcl$Price)
. It won’t work.
Remove it!
The shiny processing flow is as follows:
- Run code in
server
. - Display output in
ui
.
We’ll do this backwards.
26.30.2 Displaying output, ui side: Together
Let’s create a placeholder for the output in the ui. The *Output()
family of functions helps us with this; in this case, plotOutput()
. Common required argument: a unique outputId
for identification.
- Add
plotOutput()
with the ID"price_hist"
, to the main panel in the ui. - Run the app to see nothing has happened.
26.30.3 Displaying output, server side: Together
About:
- The
output
argument of ourserver()
function (belowui
) is a named list (actually, “list-like”) that we define, with names corresponding to the ID’s in the*Output()
functions found inui
. - Each component must contain the output of a
render*()
function; in this case,renderPlot()
. This is allowed to have R code.
Let’s put in the missing piece to making the histogram by adding a line to the server()
function:
- Add an entry:
output$price_hist
. - Make the entry the output of
renderPlot()
, whose input is the plotting codeggplot2::qplot(bcl$Price)
.
26.30.4 Displaying output: Your Turn
Use what you’ve learned about outputs to display a table of the BC Liquor data below the plot.
Hints:
- You’ll need
renderTable()
andtableOutput()
– but where? - Don’t forget to add a comma within the
mainPanel()
function when adding a new line, but NOT when defining theserver()
function! (Why?)
26.31 Inputs / Control Widgets
26.31.1 Inputs / Control Widgets: Together
Inputs /control widgets allow the user to specify input. Example: sliderInput()
. Full list available at the shiny.rstudio.com control widgets tutorial.
Arguments for all widgets:
inputId
– unique identifier.label
– “title” to the widget.- others specific to the widget.
Add this slider to the sidebar panel so that the user can select a price range:
sliderInput("priceInput", "Select your desired price range.",
min = 0, max = 100, value = c(15, 30), pre="$")
View the app. Note that the widgets aren’t yet linked to the outputs (graph and table)!
26.31.2 Inputs / Control Widgets: Your Turn
Add another widget to the sidebar panel:
- Should be a radio button widget for users to select one type of beverage, with options given in the vector below:
c("BEER", "REFRESHMENT", "SPIRITS", "WINE")
- Give the widget an ID called
"typeInput"
.
26.32 Linking Inputs to Outputs
26.32.1 Table example: Together
About:
The input
argument of our server()
function is (like output
) also a named list (actually, “list-like”). Its names are the widget ID’s, and comes “pre-made” after having defined widgets. So:
Our widget ID’s currently:
"priceInput"
, a slider."typeInput"
, a radio button.
The corresponding input
s:
input$priceInput
: a numeric vector of length 2 with the lower and upper selected range.input$typeInput
: a character vector of length 1 with the drink type.
Let’s use dplyr
to filter the table using columns Price
and Type
:
- Load
tidyverse
at the top of the script. - Filter the data in the
renderTable()
function. - Run the app. Notice the live-updating of the table after interacting with a widget.
- This is called reactive programming.
26.32.2 Plot Example: Your Turn
Modify the plot so that it only shows the filtered data.
26.33 Reactivity
26.34 The Concept of Reactivity
Will the following code output 15
or 25
?
x <- 10
y <- x + 5
x <- 20
print(y)
This is non-reactive programming. Shiny is an exception! Where is the reactivity in Shiny?
26.34.1 Defining reactive variables: Together
Can you spot the duplicate code in our app thus far? Use reactive()
to prevent duplicated code:
- Save wrangled data to a variable after passing through
reactive()
- Use this object instead of the duplicated code. Catch: treat the output like it’s a function by putting
()
next to it.
26.35 More shiny features
This concludes the “foundation of shiny”. Let’s take a look at other things we can do with shiny.
26.35.1 uiOutput()
and renderUI()
You can conditionally have UI appear as output. See an example in Section 11.1 of Dean’s tutorial.
26.36 Hosting your shiny app: shinyapps.io
You can host your app as a website for free at www.shinyapps.io
(or on your own server) – just follow the instructions. Or, see Section 13.1 in Dean’s tutorial for elaboration.
26.36.1 Interactive Rmd
Just pop runtime: shiny
in the YAML header of an Rmd file, and your ready to generate interactive HTML-based documents.
See an example in Section 14.1 of Dean’s tutorial. For an elaboration, see Chapter 19 of Yihui’s R Markdown book.
26.36.2 Interacting with plots
We can allow users to click on a graph to indicate input.
See this RStudio page for a description.
26.36.3 DT tables
Display your tables in a nicer / less static way with DT tables.
26.36.4 Shiny looks
- You can change the look of your shiny app with shinythemes.
- You can use the
shinydashboard
package for a more “website-like functionality”.