One of the beautiful gifts that R has got (that Python misses) is the package – Shiny. Shiny is an R package that makes it easy to build interactive web apps straight from R. Making Dashboard is an imminent wherever Data is available since Dashboards are good in helping Business make insights out of the existing data.

In this post, We will see how to leverage Shiny to build a simple Sales Revenue Dashboard.

Loading Packages

All the packages listed below can be directly installed from CRAN.

# load the required packages
library(shiny)
require(shinydashboard)
library(ggplot2)
library(dplyr)

Sample Input File:
Considering the fact that Dashboard needs an input data to visualise, we will use this sample recommendation.csv as input data to our dashboard but this can be modified to suit any organisational need like a Database connection or Data from remote location.

recommendation <- read.csv('recommendation.csv',stringsAsFactors = F,header=T)
head(recommendation)
       Account Product Region Revenue
1    Axis Bank     FBB  North    2000
2         HSBC     FBB  South   30000
3          SBI     FBB   East    1000
4        ICICI     FBB   West    1000
5 Bandhan Bank     FBB   West     200
6    Axis Bank    SIMO  North     200

Every shiny application has two main sections 1. ui and 2. server. ui is where the code for front-end like buttons, plot visuals, tabs and so on are present and server is where the code for back-end like Data Retrieval, Manipulation, Wrangling are present.


Image Courtesy: Slideplayer

Instead of simply using only shiny, Here we will couple it with shinydashboard. shinydashboard is an R package whose job is to make it easier (as the name suggests) to build dashboards with shiny. The ui part of a shiny app built with shinydashboard would have 3 basic elements wrapped in dashboardPage().

Simplest Shiny app with shinydashboard:

## app.R ##
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(),
  dashboardBody()
)
server <- function(input, output) { }
shinyApp(ui, server)

Gives this app:

Image Courtesy: rstudio

Aligning to our larger goal of making a Sales Revenue Dashboard, Let us look at the code of dashboardHeader() and dashboardSidebar().

#Dashboard header carrying the title of the dashboard
header <- dashboardHeader(title = "Basic Dashboard")  
#Sidebar content of the dashboard
sidebar <- dashboardSidebar(
  sidebarMenu(
    menuItem("Dashboard", tabName = "dashboard", icon = icon("dashboard")),
    menuItem("Visit-us", icon = icon("send",lib='glyphicon'), 
             href = "https://www.salesforce.com")
  )
)

To begin with dashboardPage(), We must decide what are the UI elements that we would like to show in our dashboard. Since it’s a Sales Revenue Dashboard, let us show 3 KPI boxes on the top that could represent quick summary and then 2 Graphical plots followed by them for a detailed view.

To align these elements one by one, we will define these elements inside fluidRow().

frow1 <- fluidRow(
  valueBoxOutput("value1")
  ,valueBoxOutput("value2")
  ,valueBoxOutput("value3")
)
frow2 <- fluidRow( 
  box(
    title = "Revenue per Account"
    ,status = "primary"
    ,solidHeader = TRUE 
    ,collapsible = TRUE 
    ,plotOutput("revenuebyPrd", height = "300px")
  )
  ,box(
    title = "Revenue per Product"
    ,status = "primary"
    ,solidHeader = TRUE 
    ,collapsible = TRUE 
    ,plotOutput("revenuebyRegion", height = "300px")
  ) 
)
# combine the two fluid rows to make the body
body <- dashboardBody(frow1, frow2)

It could be seen from the above code that valueBoxOutput() is used to display the KPI but what is displayed in this valueBoxOutput() will be written in the server part and the same applies for plotOutput() which is used in the ui part to display a plot. box() is a function provided by shinydashboard to enclose the plot inside a box with certain features like title, solidHeader and collapsible. Having defined two fluidRow() functions individually for the sake of modularity, we can combine both of them in dashbboardBody().

Thus we can complete the ui part comprising Header, Sidebar and Page with the below code:

#completing the ui part with dashboardPage
ui <- dashboardPage(title = 'This is my Page title', header, sidebar, body, skin='red')

Note that the value of title in dashboardPage() will serve as the title of the browser page/tab, while the title defined in the dashboardHeader() will be visible as the dashboard title.

With the ui part over, We will create the server part where the program and logic behind valueBoxOutput() and plotOutput() are added with renderValueBox() and renderPlot() respectively, enclosed inside server function with input,output as its paramaters. Values inside input contain anything that is received from ui (like textBox value, Slider value) and Values inside output contain anything that is sent to ui (like plotOutput, valueBoxOutput).

Below is the complete server code:

# create the server functions for the dashboard  
server <- function(input, output) { 
  #some data manipulation to derive the values of KPI boxes
  total.revenue <- sum(recommendation$Revenue)
  sales.account <- recommendation %>% group_by(Account) %>% summarise(value = sum(Revenue)) %>% filter(value==max(value))
  prof.prod <- recommendation %>% group_by(Product) %>% summarise(value = sum(Revenue)) %>% filter(value==max(value))
#creating the valueBoxOutput content
  output$value1 <- renderValueBox({
    valueBox(
      formatC(sales.account$value, format="d", big.mark=',')
      ,paste('Top Account:',sales.account$Account)
      ,icon = icon("stats",lib='glyphicon')
      ,color = "purple")  
  })
  output$value2 <- renderValueBox({ 
    valueBox(
      formatC(total.revenue, format="d", big.mark=',')
      ,'Total Expected Revenue'
      ,icon = icon("gbp",lib='glyphicon')
      ,color = "green")  
  })
output$value3 <- renderValueBox({
    valueBox(
      formatC(prof.prod$value, format="d", big.mark=',')
      ,paste('Top Product:',prof.prod$Product)
      ,icon = icon("menu-hamburger",lib='glyphicon')
      ,color = "yellow")   
  })
#creating the plotOutput content
  output$revenuebyPrd <- renderPlot({
    ggplot(data = recommendation, 
           aes(x=Product, y=Revenue, fill=factor(Region))) + 
      geom_bar(position = "dodge", stat = "identity") + ylab("Revenue (in Euros)") + 
      xlab("Product") + theme(legend.position="bottom" 
                              ,plot.title = element_text(size=15, face="bold")) + 
      ggtitle("Revenue by Product") + labs(fill = "Region")
  })
output$revenuebyRegion <- renderPlot({
    ggplot(data = recommendation, 
           aes(x=Account, y=Revenue, fill=factor(Region))) + 
      geom_bar(position = "dodge", stat = "identity") + ylab("Revenue (in Euros)") + 
      xlab("Account") + theme(legend.position="bottom" 
                              ,plot.title = element_text(size=15, face="bold")) + 
      ggtitle("Revenue by Region") + labs(fill = "Region")
  })
}

So far, we have defined both the essential parts of a Shiny app – ui and server. And finally we have to call/run the shinyApp with ui and server as its paramters.

#run/call the shiny app
shinyApp(ui, server)
Listening on http://127.0.0.1:5101

The entire file has to be saved as app.R inside a folder before running the shiny app. Also remember to put the input data file (in our case, recommendation.csv inside the same folder where app.R is saved). While there is another valid way to structure the shiny app with two files ui.R and server.R (optionally, global.R), it has been ignored in this article for the sake of brevity since this is aimed at beginners.

Upon running the file, the shiny web app would open in your default browser and would look similar to the below screenshot:

Hopefully at this stage, You have got your shiny web app in the form of Sales Revenue Dashboard up and running. The code and plots used here are available on my Github.

References