Introduction to Shiny

Shiny is an R application that allows users to build interactive web applications easily in R! You can make your own apps in Shiny without the knowledge of programming languages like Java, HTML or CSS. Shiny is an powerful extremely tool. Unlike the more traditional workflow of creating presentations, you can now create an app that allows your readers to change the assumptions underlying your analysis and see the results immediately. When you work on a project and you want to share your project with your peers, instead of making long static reports, you can just make an app of all the statistical analysis you have done on your project and share it! It reduces the effective time by more than 80% and makes documentation fun and interactive!

Let us now see the 7 basic steps for making your own app.

Step 1: New to Shiny!

First you’ll have to install the shiny package from Cran on Rstudio. You can do that by the following function:

install.packages("shiny",repos = "http://cran.us.r-project.org")
library(shiny)

There are some inbuilt examples made in Shiny to understand the scope and various functionalities of it. Run the first example with the code given below

runExample("01_hello")

Step 2: Understand the structure of Shiny app!

A Shiny app consists of 2 main components

  1. Server script (server.R)
  2. User Interface script (ui.R)

The user - interface script controls the layout and the appearance of your app. It is defined and stored with the name ui.R. The server script contains the instructions that your computer needs, to build the app. It is defined and stored with the name server.R

Note: Your server script and user-interface script should be in the same working directory as your app. Create a new directory named Example_app in your working directory. Then copy - paste your ui.R and server.R scripts within this app. Your working directory will look like this

alt text

You can check your working directory by getwd() function and set it where you’d like by setwd() or manually on R studio by clicking on Session.

Step 3: Layout of the app

The basic structure of the user-interface and the server script is:

library(shiny)

shinyUI(fluidPage(
  titlePanel("This is the title Panel!"),
  sidebarLayout(
    sidebarPanel("This is the Sidebar Panel",
                 br(),
                 br(),
                 br(),
                 p("By default it is placed on Left")),
    mainPanel("This is the main Panel")
    )))

This is the title Panel!

This is the Sidebar Panel


By default it is placed on Left

This is the main Panel

shinyServer(
  function(input,output){
    
  })

The script above will make you understand the basic layout of the app. It also explains the basic structure of ui.R and server.R. The argument fluidPage makes the app page responsive and can enable the app to work on any platforms without affecting the layout of the app. Fluid pages scale their components in realtime to fill all available browser width.

The user interface consists of 2 basic Panels:

  • Title Panel
  • Sidebar Layout
    • Sidebar panel
    • Main panel

Most of the inputs of the shiny app is presented in the sidebar panel with the output in the main panel. However this is subject to change according to the requirement of the app.

Note: The br() function is only providing a line space in the user-interface. You can try running this example even without the br() function.

Its your turn. Run the basic structure of the app, to see how it looks like. Make some changes to experiment and ploy around with it

Step 4: Add widgets to your app

We’ll now create the app which will look like this. It will allow you to see the summary of the chosen variable of the iris dataset and create a boxplot of the variable.

alt text

This is the code of your app, let’s see a step by step execution of how we create this. We’ve already defined the title panel. Now we’ll define some widgets in our sidebar panel.

# ui.R

shinyUI(fluidPage(
    titlePanel("My first Shiny app!"),
  sidebarLayout(
    sidebarPanel(
    selectInput("var",label="Choose a variable",choice=c("Sepal.Length"=1,
                                                                  "Sepal.Width"=2,
                                                                  "Petal.Length"=3,
                                                                  "Petal.Width"=4), selectize=FALSE)),
    mainPanel(
      h2("Summary of the variable"),
      verbatimTextOutput("sum"),
      plotOutput("box")
      )
    ))
  )
# server.R
 
library(shiny)
library(datasets)

  shinyServer(function(input,output){
    
    output$sum <- renderPrint({
      
      summary(iris[,as.numeric(input$var)])
      })
    
    output$box <- renderPlot({
      
      x<-summary(iris[,as.numeric(input$var)])
      boxplot(x,col="sky blue",border="purple",main=names(iris[as.numeric(input$var)]))
    })
  }
)

Here the data we have used is from the already existing library of datasets in R. You can access this dataset by calling the library(datasets) function. We have used the iris dataset here. You can understand about the iris dataset by calling ?iris function in your R Console.

Widgets - Control widgets are web elements that your users can interact with. Widgets provide input to your Shiny app. For eg: In our Example_app above, the button where you select the variable is a widget. It lets the user select the input for which the summary is provided in the main panel. Mostly the widgets are placed in the sidebarpanel. Shiny has a list of inbuilt widgets which you can access here on Widget Gallery

The widget we have used here is selectInput, the code for which is

selectInput(inputId="var",label="Choose a variable",choice=c("Sepal.Length"=1,
                                                                  "Sepal.Width"=2,
                                                                  "Petal.Length"=3,
                                                                  "Petal.Width"=4),selectize= FALSE)

The inputId is the value with which the widget is stored. This is for internal computational purposes. label is used just for user-interface, it can also be blank. To know more you can call ?selectInput function.

Step 5: Make your app reactive!

After you’ve given the input, you also need to ensure that the output is displayed. The shiny server function has function(input,output) notation given to it where we’ll define the function. Also we will need to describe to shiny where to display the output. Here we’re displaying the output in the main panel. The code that’ll follow will look like this:

mainPanel(
      h2("Summary of the variable"),
      verbatimTextOutput("sum"),
      plotOutput("box")
      )

We’ve two outputs in our main panel. One is displaying the ‘summary’ and the other is the ‘boxplot’ of the selected variable. Therefore we’ve defined two outputs in our main panel. verbatimTextOutput(outputId="sum") and plotOutput(outputId="box") These render a reactive output variable within an application page. A reactive output is created with a 2 step process:

  • Defining an R object to the user interface ui.R Here we’re defining two objects in the main panel.
    • verbatimTextOutput which prints the output of the summary exactly in the same format as it is built in R. Shiny provides a family of functions that turn R objects into output for your user-interface. Each function creates a specific type of output. You can experiment with other objects to see what output they provide!
    • plotOutput which allows shiny to plot the boxplot of the variable.
  • Define how to build the object in server.R
    • The R object will be reactive only when it responds to the changes in value of the widget. In this case, we do that by defining the render* function against the defined R object. i.e renderPrint and renderPlot
    • Each render* function takes a single argument: an R expression surrounded by {} braces. This R expression is a set of instructions you give shiny to store for later. Shiny will run these instructions the first time you launch the app and re-run it everytime you update your app. For this to work your expression should return the type of object you have called (it may be text, plot, a table, data frame etc.)

Use the Widgets

In your server.R code, within the function we have defined two variables: input and output. The app will not be reactive unless you call both the variables.

library(datasets)
shinyServer(
  
  function(input,output){
})

The input here is the widget value that is called each time when the input changes and the output is defined as below:

shinyServer(
  function(input,output){
    
    output$sum <- renderPrint({
      
      summary(iris[,as.numeric(input$var)])
    })    
  })

Here we are defining our output according to the R-object we’ve defined in the user-interface, which is to print the summary of iris dataset as it is. But the variable selected is dependent on the widget and hence we define input$var in the summary which makes the app reactive. Since selectInput function stores the values of widgets as a character, we’ve coerced it to numeric by as.numeric function. To see, how each widget stores its values internally, you can visit the Widget Gallery page here.

Step 6: Launch your app!

You can do that by running the command runApp("Your_app_name") in your R console! You can also choose to launch your app, highlighting the reactive output each time the widget value changes by adding the argument display= showcase in your runApp command, like this: runApp("Your_app_name",display="showcase")

Step 7: Share it with your friends!

You can share your app with friends by deploying it on shinyApps.io or using Shiny server pro. More on this will be covered in the next article!

Hope you enjoyed reading this!