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().
-
1. dashboardHeader(),
2. dashboardSidebar(),
3. dashboardBody()
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
-
1. The basic parts of a shiny app
2. Get Started – Shinydashboard
3. Shiny Files Structure
4. Input recommendation.csv file (right click and save as
recommendation.csv
)