Skip to main content

Building my first R Shiny app -> Covid19 status for: France, UK, Italy, Germany, Poland, Spain.

 The report I will show here consists of two charts: line chart and scatterplot. On the left top corner you can choose country (one of six) and accordingly the report will present this two graphs for the selected country. On the right sight of the report you will see small table and check box for Scatterplot chart. You can choose scatterplot with or without regression line. The report looks like this  https://karolinamgoma.shinyapps.io/covid19/

I will explain you step by step how to build such shiny app by yourself. It will be useful to read my previous post so you can already be able to create your app.R script. If your app.R already exist we can add some libraries which I am going to use. Install them if you don't have it yet.

Libraries
library(shiny) # for building web app
library(readr) #data import tool, part of the Tidyverse.
library(dplyr) #perfect package for data manipulation, queries and much more, part of the Tidyverse.
library(ggplot2) #package for data visualizations, part of the Tidyverse.
library(RColorBrewer) #package which is helpful while we are choosing the colours.
library(shinythemes) #package for choosing particular theme for your app

Data&transformations

I downloaded data file "COVID_data_2021_01_19" from https://shiny.rstudio.com/gallery/covid19-tracker. Thanks to readr package I import dataset to R and transform it a bit. I used dplyr to pick some observations I wanted to visualized therefore I created "covid2" data.frame.

covid<-COVID_data_2021_01_19 
covid$country=as.factor(covid$country)
covid$date=as.Date(covid$date,format='%m%d%y')
covid=as.data.frame(covid)
covid2<- covid%>%filter(country == c("France","Poland","UK","Germany","Spain","Italy"))%>%as.data.frame()
country<-covid2$country%>%unique()

As I was mentioned in the previous post, each shiny app has got three components: ui, sever and shinyApp() function. I will describe step by step each of them.

User Interface

Each ui starts with fluidPage() function. As you can see we add shinythemes library because I decided to use "flatly" shinytheme to make all report nicer. There are other choices of course.  It is good to visit https://rstudio.github.io/shinythemes/ so you can pick one which suits you best. With the function titlePanel() I add title to my report.

Now it is time to use the layout. I have chosen Grid Layout which has the following structure, for example: fluidRow( column(6) #it will be half of the page, column(4) #it will be 1/3 of the page). All page consist of 12 columns. User Interface collect user Input and display Output. Therefore next I defined my Input "selected_country". It is the country the user is choosing. I did it with the function selectInput(inputid, label).

I added some text by using HTML functions like h3() which gives 3ed level headings, h5() which gives 5th level headings. After I define Output: "country_name", "linechart_plot", "cumulative_table", "scatterplot", "lm". Checkbox I defined with function checkboxInput().

The code is the following:

ui <- fluidPage(theme = shinytheme("flatly"), # I decided to use "flatly" shinytheme 
titlePanel("Covid 19 status per country"), #I add title to my report 
fluidRow( # Grid Layout 
column(4, #it will be displayed in 1/3 of the page selectInput("selected_country","Country", # I defined inputid, label
choices=country,selected="France"), #I defined choices and I put the first choice for France
h3(textOutput("country_name"))), #Display the name of the chosen country as 3red level headings.
),
fluidRow(
column(8, # We define output for line chart plot, for 2/3 of the page
plotOutput("linechart_plot")),
column(4,
tableOutput("cumulative_table")), #We define another output which is a table with some statistics.
br(),# a line of space
br(),
h5("Data was taken from the https://shiny.rstudio.com/gallery/covid19-tracker."),
h5("This report shows the situation in six European countries:",span(" France, UK, Italy, Germany, Poland, Spain",style = "color:brown"), strong("from April 2020 till the beginning of January 2021."), aglin="center")
), # with HTML functions we display part of the text
fluidRow(
column(8,
plotOutput("scatterplot")), #We define output for Scatterplot, for 2/3 of the page
column(4,
checkboxInput("lm","Linear regresion line")), #Adding checkbox
))
Server

Server function contains recipe for output. We define it with the render function. If in the ui we defined textOutput, in server we will have to use renderText(). For plotOutput, we will have renderPlot() and for tableOutput will be renderTable().

If you noticed some duplications in your code, it is useful to use reactive () function. Because of this we will not have to repeat the same lines several time.

To create line chart and Scatterplot I am using ggplot2. I am using some functions for formatting the charts. I recommends to see my previous post about ggplot2 when I explained in details the formulas.

The code is the following:

server <- function(input, output, session) {
    output$country_name<-renderText(input$selected_country)
    filter_country<-reactive({covid2%>%filter(country==input$selected_country)}) #This part of code exist in two places therefore thanks to reactive() will not have to repeat it
    output$linechart_plot<-renderPlot({ # I am giving the recipe for line chart
filter_country()%>% ggplot(aes(x=date, y=cumulative_cases, color=input$selected_country))+ geom_line(size=1.25,color="brown")+ theme_gray(base_size = 12)+ ggtitle("Number of covid 19 cases from April 2020 - January 2021")+ theme(plot.title=element_text(hjust=0.5,face = "bold"))+ xlab("Month")+ ylab("Number of cases")+ theme(panel.background = element_rect(fill="cornsilk"))+ guides(color=guide_legend(title = "Country", label.position = "right", reverse=T))+
        scale_x_date(date_breaks = "1 month",
                     date_labels = "%b",
                limits = as.Date(c("2020-04-01", "2021-01-12")))
    })
    
    output$cumulative_table<-renderTable(digits = 0,{ # I am giving the recipe for creating a table with some statistics.Thanks to digits=0 no values after comma.
 covid2%>% summarise(Country=input$selected_country, Total_number_covid19_cases=max(cumulative_cases), Total_number_of_deaths=max(cumulative_deaths))
    })

    output$scatterplot<-renderPlot({ # I am giving the recipe for Scatterplot.
    plot_scatterplot<-function(selected_country=input$selected_country,lm=input$lm){
        p<-filter_country()%>% ggplot(aes(x=cumulative_deaths,y=cumulative_cases,color=input$selected_country))+ geom_point(size=3,color="brown")+ ggtitle("Correlation between number of deaths vs.\n number of cases per country")+ xlab("Number of deaths")+ ylab("Number of cases") + theme_grey(base_size = 14)+ theme(plot.title=element_text(hjust=0.5,face = "bold"))+ theme(panel.background element_rect(fill="cornsilk"))+guides(color=guide_legend(title = "Country", label.position = "right", reverse=T))
        
        if(isTruthy(lm)){ # According to what the user will chose, the plot display additional regression line. isTruthy() let me avoid error with if condition. Error was that "argument is lenght of 0".
          
          p<-p+geom_smooth(method="lm",size=0.75,color="darkgoldenrod")
        }
        p
      }
      
      plot_scatterplot()
    
    })
}

Shiny app

The last element is to call function shinyApp().

shinyApp(ui, server) # shinyApp() for creation the app


Comments

Popular posts from this blog

Random number generators, reproducibility and sampling with dplyr

Let's assume that you want to take some random observations from your data set. Dplyr helps you with the function sample_n(). To make your code reproducible you seed the ID of a “random” set of values. You need to indicate number of rows you want to extract and specify if the rows should be replaced or not. To show you how it works I will use again mtcars dataset which is included in your base R program. Let's see first six rows of this data frame.  library(dplyr) data("mtcars") head(mtcars)                    mpg cyl disp  hp drat    wt  qsec vs am gear carb Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4 Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4 Datsun 710        22.8   4  108  93 3.85 2.320 18.61...

Ggplot2 for data visualizations

 When I have started my adventure with R, immediately I've noticed that everybody was taking about ggplot2 and its importance.  Tap "ggplot2"  in google and check it by yourself.  You will see a lots of professional fancy graphs, articles, blogs and other great materials.  I was so impressed  that I was even trying to start my learning of R programming from ggplot2.  Soon I understood, that I needed some basics first and it is better to take time if you are starting from zero. Before jumping to the ggplot2 structure I will share with you some tips I find useful. First it is good to remember that there are some steps while you explore your data. Most of the time you have to collect data first,  do some pre-processing and exploration,  modelling & analysis and only after comes visualization. Of course in previous steps,  graphs also can be helpful to interpret the situation correctly however it is important that you have prepared, clea...

Basic Statistics for Time Series

What we can say about the time series data at the beginning? How we can describe it and what elements determinate the method we will use to forecast the data? For my own personal use I have prepared some notes which help me to answer questions above. I was using some definitions from the book of "Forecasting: Principles & Practice" by Rob J Hyndman like also some other blog's article like: https://towardsdatascience.com/descriptive-statistics-in-time-series-modelling Basic Statistics for Time Series When you make sure that your data has time series class, you can check the data with the basic functions we have in R. ts() is useful to build Time Series from scratch. mean() shows the average of a set of data. median() shows the middle value of the arranged set of data. plot() shows on the graph how the Time series looks like sort() sort the data quantile() function returns quantiles which are cut points dividing the range of a probability distribution into continuous ...