10 R Shiny

10.1 Introduction

Shiny (Chang et al. 2021) is a web application framework for R that enables to build interactive web applications.

The R shiny Cheatsheet can be found HERE

The Big Concept

Interact. Analyze. Communicate.

Take a fresh, interactive approach to telling your data story with Shiny. Let users interact with your data and your analysis. And do it all with R.

If you’ve never used Shiny before, welcome! Shiny is an R package that allows you to easily create rich, interactive web apps. Shiny allows you to take your work in R and share it through a web browser .

In the past, creating web apps was hard for most R users because:-

You need a deep knowledge of web technologies like HTML, CSS, JavaScript, server configuration.

How do Data Analysts and Scientists use R :-

  • To create dashboards that track important high-level performance indicators, while facilitating drill down into metrics that need more investigation.

  • To replace hundreds of pages of PDFs with interactive apps that allow the user to jump to the exact slice of the results that they care about.

  • To communicate complex models to a non-technical audience with informative visualisations and interactive sensitivity analysis.

  • To provide self-service data analysis for common workflows, replacing email requests with a Shiny app that allows people to upload their own data and perform standard analyses. You can make R analyses available to users with no programming skills. e.g. This App

In short, Shiny gives you the ability to pass on some of your R superpowers to anyone who can use the internet to access the web.

To create Shiny apps, there is no web development experience required, although greater flexibility and customization can be achieved by using HTML, CSS or JavaScript.

While there is a wealth of material available on the internet to help you get started with Shiny, it can be difficult to see how everything fits together. This guide will take a fairly predominantly live coding approach, rather than a lecture-only approach.

This section will teach you the basics of Shiny app programming, giving you skills that will form the basis of almost any app you want to build. By the end of the section, you will have created a custom shiny app.

10.1.1 Some sample of Live Shiny Apps

The following are some diverse examples of Shiny apps :-

  • Pearl Tap Into Twitter: This dashboard is part of the Pearl Data Firm Ecosystem, This dashboard can be used to monitor your twitter marketing campiagns.

  • R Shiny Whatsapp Chat Analyser Tool:This is an Interactive R shiny Application that enables upload of a your chat from whatsapp, and generates visualizations and descriptive statistics to help track, analyze, and to gain deeper insight in your chats.

  • Charcoal Equivalent Statistics: An application tool to estimate the equivalent grid power and number of trees that would replace a given percentage of heating functions done by charcoal.

  • HK Data Analyzer: An Interactive R shiny Application that enables upload of a data set based on HK Data template, and generates visualizations and descriptive statistics to help track, analyze and gain insights.

  • Shiny Enterprise Dashboard: A more advanced Shiny Application

  • And Many More

10.1.2 What experience do I need?

You need to have basic familiarity with R, including data import, data processing, visualization, and functions and control structures (e.g., if/else). Instruction will be done using RStudio.

Some familiarity with ggplot2 and dplyr would be useful. You definitely do not need to be an expert coder, but the following code should not be challenging to understand.

If you want to brush up on your R , this self study guide provides a comprehensive overview.

In this section you will learn about :-

  • The basic principles to build a Shiny app.

  • How to build the user interface and server parts of a shiny app

  • How to create reactivity.

  • How to design a basic layout for the user interface

  • How to share with others you application.

Therefore, this section is designed to take you from knowing nothing about Shiny to being able to develop shiny apps to help you share your analysis in an interactive way.

However,More advanced topics such as customization of reactions and appearance of the app can be found in the Shiny tutorials website. Examples of more advanced Shiny apps can be seen in the Shiny gallery.

10.2 Structure Of a shiny App

10.2.1 Basic file structures

To understand shiny, we first need to understand how the file structure of an app works!

Note:

You need to make a brand new directory before we start. This can actually be made easier by choosing New project in Rstudio, and choosing Shiny Web Application. This will create the basic structure of a shiny app for you.

When opening this project, you’ll notice there is a .R file already present called app.R. It is essential that we have one of two basic file structures:

  1. One file called app.R, or

  2. Two files, one called ui.R and the other server.R

However, i personally prefer and recommend a two files structure.

  • The two files help you not to have a length code in one file, hence avoiding longer scrolling,

  • Also makes following up your code workflow especially if the code is extensive, AND

  • most of the Shiny apps I come accross seem to follow the convention of using differente files.

    BUT, does is make any difference, technically?

10.3 Building the UI

Since you have creating your first basic shiny App, Let’s now explore the details that make your UI more have more functionality.

In this sub section , we are going to focus on the front end, and look at a number of the inputs and outputs provided by Shiny. These gives you the ability to capture many types of data and display many types of R output.

Not that there are very many shiny extensions for advanced added functionality that we may not look at here such as shinyWidgets, colorpicker, etc. There is a comprehensive, actively-maintained list of other packages extensions HERE.

10.3.1 Inputs

The following are standard Shiny input widgets (click the image below to view a live app demostration)

function widget
actionButton Action Button
checkboxGroupInput A group of check boxes
checkboxInput A single check box
dateInput A calendar to aid date selection
dateRangeInput A pair of calendars for selecting a date range
fileInput A file upload control wizard
helpText Help text that can be added to an input form
numericInput A field to enter numbers
radioButtons A set of radio buttons
selectInput A box with choices to select from
sliderInput A slider bar
submitButton A submit button
textInput A field to enter text

10.3.1.1 Adding an Input widget to the app

All input functions functions have the same format;-

  • inputId. This is the unique identifier used to connect the UI with the SERVER. if your UI has an input with ID "amount", the server function will access it with input$amount.

    Note that the inputId must be a simple text that follow the rules of indentifies i.e.

    • unique

    • contains only letters, numbers, and underscores (no spaces, dashes, periods, or other special characters allowed!).

  • label. This is used to create a human-readable label for the control. Shiny doesn’t place any restrictions on this string, but you’ll need to carefully think about it to make sure that your app is usable by humans!

  • value, Enables you set the default value.

    Note that: The other remaining arguments are unique to each input function

Some Examples of Inputs

10.3.1.2 Inputting a text

Collect small amounts of text with textInput(), passwords with passwordInput(), and paragraphs of text with textAreaInput().

fluidRow(textInput("username", "Enter user Name?"), passwordInput("password",
    "Enter password?"), textAreaInput("describe", "In One Sentence,Describe yourself",
    rows = 4))

10.3.1.3 Inputting numeric inputs

To collect numeric values, create a text box with numericInput() or a slider with sliderInput().

fluidPage(numericInput("age", "What is your Age", value = 0,
    min = 0, max = 120), sliderInput("rate", "Out of 10, How do you rate your R skills",
    value = 5, min = 0, max = 10), sliderInput("score", "What was your Score in R test",
    value = c(0, 50), min = 0, max = 100))

Sliders are extremely customization and there are many ways to tweak their appearance. See ?sliderInput and https://shiny.rstudio.com/articles/sliders.html for more details.

10.3.1.4 Inputting Dates

Collect a single day with dateInput() or a range of two days with dateRangeInput(). These provide a convenient calendar picker, and additional arguments like datesdisabled and daysofweekdisabled allow you to restrict the set of valid inputs.

fluidRow(dateInput("dob", "Enter you date of birth?"), dateRangeInput("start_course",
    "When do you expect to Practce R?"))

Date format, language, and the day on which the week starts defaults to US standards. If you are creating an app with an international audience, set format, language, and weekstart so that the dates are natural to your users.

10.3.1.5 Inputting from choices

There are two different approaches to allow the user to choose from a prespecified set of options: selectInput() and radioButtons().

selectInput(inputId = "language1", label = "Which Language are you most proficient?",
    choices = c("R", "Python", "C", "C++", "SQL", "HTML", "JavaScript"))
radioButtons(inputId = "language2", label = "What other languages do you Know?",
    choices = c("R", "Python", "C", "C++", "SQL", "HTML", "JavaScript"))

Radio buttons have two nice features: they show all possible options, making them suitable for short lists, and via the choiceNames/choiceValues arguments, they can display options other than plain text. choiceNames determines what is shown to the user; choiceValues determines what is returned in your server function.

radioButtons("status", "How are you?", choiceNames = list("angry",
    "happy", "sad"), choiceValues = c(1, 2, 3))

If you have a very large set of possible options, you may want to use “server-side” selectInput() so that the complete set of possible options are not embedded in the UI (which can make it slow to load), but instead sent as needed by the server. You can learn more about this advanced topic at https://shiny.rstudio.com/articles/selectize.html#server-side-selectize.

There’s no way to select multiple values with radio buttons, but there’s an alternative that’s conceptually similar: checkboxGroupInput().

checkboxGroupInput(inputId = "skills_known", label = h3("Select the packages you know"),
    choices = list(shiny = 1, tidyverse = 2, rhino = 3, ggplot2 = 4,
        lubridate = 5, htmltools = 6, others = 7), selected = 1)

10.3.1.6 File uploads

Allow the user to upload a file with fileInput()

fileInput(inputId = "data_upload", label = "Upload your data",
    NULL)

fileInput() requires special handling on the server side, and is discussed in detail latyer in th section.

10.3.1.7 Action buttons

Let the user perform an action with actionButton() or actionLink():

fluidRow(actionButton("view_data", "Click me to View Data"),
    actionButton("model", "Run Model", icon = icon("cogs")))

Actions links and buttons are most naturally paired with observeEvent() or eventReactive() in your server function.

You can customise the appearance using the class argument by using one of "btn-primary", "btn-success", "btn-info", "btn-warning", or "btn-danger". You can also change the size with "btn-lg", "btn-sm", "btn-xs". Finally, you can make buttons span the entire width of the element they are embedded within using "btn-block".

fluidRow(actionButton("view_data2", "Click me to View Data",
    class = "btn-warning"), actionButton("model2", "Run Model",
    icon = icon("cogs"), class = "btn-info"))

The class argument works by setting the class attribute of the underlying HTML, which affects how the element is styled. To see other options, you can read the documentation for Bootstrap, the CSS design system used by Shiny: http://bootstrapdocs.com/v3.3.6/docs/css/#buttons.

10.3.2 Outputs

Outputs in the UI create placeholders that are later filled by the server function.

Shiny provides a family of functions that turn R objects into output for your user interface. Each function creates a specific type of output.

Output function Creates
dataTableOutput DataTable
htmlOutput raw HTML
imageOutput image
plotOutput plot
tableOutput table
textOutput text
uiOutput raw HTML
verbatimTextOutput text

Like inputs, outputs take a unique ID as their first argument, if your UI specification creates an output with ID "plot", you’ll access it in the server function with output$plot.

10.3.2.1 Text Output

Output regular text with textOutput() and fixed code and console output with verbatimTextOutput().

10.3.2.2 Tables Output

There are two options for displaying data frames in tables:

tableOutput() is most useful for small, fixed summaries (e.g. model coefficients); dataTableOutput() is most appropriate if you want to expose a complete data frame to the user.

10.3.2.3 Plot Output

You can display any type of R graphic with plotOutput() and renderPlot():

10.3.2.4 Downloads

You can let the user download a file with downloadButton() or downloadLink().

10.3.3 HTML content

The appearance of a Shiny app can be customized by using HTML content such as text and images. We can add HTML content with the shiny::tags object. tags is a list of functions that build specific HTML content. The names of the tag functions can be seen with names(tags). Some examples of tag functions, their HTML equivalents, and the output they create are the following:

  • h1(): <h1> first level header,

  • h2(): <h2> second level header,

  • strong(): <strong> bold text,

  • em(): <em> italicized text,

  • a(): <a> link to a webpage,

  • img(): <img> image,

  • br(): <br> line break,

  • hr(): <hr> horizontal line,

  • div: <div> division of text with a uniform style.

We can use any of these tag functions by subsetting the tags list. For example, to create a first level header we can write tags$h1("Header 1"), to create a link to a webpage we can write tags$a(href = "www.webpage.com", "Click here"), and to create a section in an HTML document we can use tags$div().

Some of the tag functions have equivalent helper functions that make accessing them easier. For example, the h1() function is a wrapper for tags$h1(), a() is equivalent to tags$a(), and div() is equivalent to tags$div(). However, most of the tag functions do not have equivalent helpers because they share a name with a common R function.

We can also include an HTML code different from the one that is provided by the tag functions. To do that, we need to pass a character string of raw HTML code to the HTML() function: tags$div(HTML("<strong> Raw HTML </strong>")). Additional information about tag functions can be found in Customize your UI with HTML and the Shiny HTML Tags Glossary.

10.3.4 Layouts

Shiny includes a number of facilities for laying out the components of an application. They include :

  1. A sidebarLayout(): for placing a sidebarPanel() of inputs alongside a mainPanel() output content.

  2. Custom layouts using Shiny’s grid layout system (i.e., fluidRow() & column()).

  3. Segmenting layouts using the tabsetPanel() and navlistPanel() functions.

  4. Creating applications with multiple top-level components using the navbarPage() function.

The outlook can be customized manually or by applying application themes, check out the application themes article here .

10.3.4.1 Sidbar Layout

This layout provides a sidebar for inputs and a large main area for output:

fluidPage(titlePanel("Side bar Layout!"), sidebarLayout(sidebarPanel(),
    mainPanel()))

Grid Layout

The familiar sidebarLayout() described above makes use of Shiny’s lower-level grid layout functions. Rows are created by the fluidRow() function and include columns defined by the column() function. Column widths are based on the Bootstrap 12-wide grid system, so should add up to 12 within a fluidRow() container.

To illustrate, here’s the sidebar layout implemented using the fluidRow(), column() and wellPanel() functions:

fluidPage(titlePanel("Crid Layout"), fluidRow(column(4, wellPanel(sliderInput())),
    column(8, )))

10.3.4.2 Tabsets

Often applications need to subdivide their user-interface into discrete sections. This can be accomplished using the tabsetPanel() function.

fluidPage(titlePanel("Tabset layout"), sidebarLayout(sidebarPanel(),
    mainPanel(tabsetPanel(tabPanel("tab1"), tabPanel("tab2"),
        tabPanel("tab3")))))

10.3.4.4 Shiny Dashboard.

A dashboard has three parts: a header, a sidebar, and a body. Here’s the most minimal possible UI for a dashboard page.

You can learn more about customizing dashboards HERE

HTML content

The appearance of a Shiny app can be customized by using HTML content such as text and images. We can add HTML content with the shiny::tags object. tags is a list of functions that build specific HTML content. The names of the tag functions can be seen with names(tags). Some examples of tag functions, and the output they create include:

  • h1(): first level header,

  • h2(): second level header,

  • strong(): bold text,

  • em(): italicized text,

  • a(): link to a webpage,

  • img(): image,

  • br(): line break,

  • hr(): horizontal line,

  • div(): division of text with a uniform style.

We can use any of these tag functions by subsetting the tags list. For example,

  • to create a first level header we can write tags$h1("Header 1"),

  • to create a link to a webpage we can write tags$a(href = "www.webpage.com", "Click here"),

  • to create a section in an HTML document we can use tags$div().

The h1() function is a wrapper for tags$h1(), a() is equivalent to tags$a(), and div() is equivalent to tags$div(). However, most of the tag functions do not have equivalent helpers because they share a name with a common R function.

Additional information about tag functions can be found in Customize your UI with HTML and the Shiny HTML Tags Glossary.

10.4 Sharing Shiny apps

Now that you can develop a shiny app, you probably wondering how to share it with others - this is the main advantage of shiny after all

There are two options to share a Shiny app with other users.

  1. You can directly share the R scripts we used to create the Shiny app with them locally or may be version control platforms like GITHUB, Learn more about usng Github with R HERE. (If they know how to use R and are OK with it, and also for code reviews), or

  2. We can host the Shiny app as a webpage with its own URL.

With this option, other users do not need to have R installed which permits the use of the app by people without R knowledge. We can host the Shiny app as a webpage on its own server, or we can host it using one of the several ways RStudio offers such as Shinyapps.io and Shiny Server. Information about these options can be obtained by visiting the Shiny hosting and deployment website.

    • shinyapps.io: this is the easiest place to publish shiny apps, as it has the smallest amount of configuration work needed, and has some free, but limited licenses.
    • RStudio Connect: this is a far more powerful version of an R server, that can perform many operations, including publishing shiny apps. It is however, harder to use, and less recommended for first-time users.

For personal use, i reccomend the R shiny server Shinyapps.io .

shinyapps.io is a shared hosting environment managed by RStudio. Both free and paid tiers are available. This hosting platform is most commonly used in non-enterprise environments.

10.4.1 Steps to deploy on shinyapps.io

  1. should make sure our app is suitable for publishing on a server. In your app, you should restart your R session, and ensure that it runs without running any extra code. This is important, as an app that requires package loading, or data reading not defined in your app code won’t run on a server. Also note that you can’t have any explicit file paths in your app - these will be invalid in the server setting.

  2. Signing up for account on shinyapps.io

  3. Once you have your account, you can navigate to the tokens page under Accounts. Here you will want to add a new token - this will be used to deploy your app.

  4. You can deploy you app following the steps HERE. The steps mentioned above are very detailed.

10.5 Lets buid a Shiny App together