How to Build COVID-19 Data-Driven Shiny Apps in 5mins

Build shiny apps with COVID-19 Data Hub. A fully functioning example in 20 lines of code.

Emanuele Guidotti
Emanuele Guidotti

Many databases exist in connection with COVID-19, but no virtual platform currently integrates a significant proportion of these sources. It then becomes difficult to make a global analysis, and to make connections between this often-medical information and external factors, notably socio-political. With this in mind, COVID-19 Data Hub aims to develop a unified dataset helpful for a better understanding of COVID-19.

In this tutorial we are going to build a simple yet complete Shiny application using the R Package COVID19: R Interface to COVID-19 Data Hub.

A basic understanding of Shiny (web apps) and plotly (interactive plots) is assumed, but it is possible to build a fully functioning app simply by copy/paste. Load the following packages to get started:



The COVID19 R package provides a seamless imtegration with COVID-19 Data Hub via the covid19() function. Type ?covid19 for the full list of arguments. Here we are going to use:

  • country: vector of country names or ISO codes.
  • level: granularity level; data by (1) country, (2) region, (3) city.
  • start: the start date of the period of interest.
  • end: the end date of the period of interest.

Define UI

Define the following inputs…

  • country: the country name. Note that the options are automatically populated using the covid19() function.
  • type: the metric to use. One of c("confirmed", "tests", "recovered", "deaths"), but many others are avaibale. See here for the full list.
  • level: granularity level (country - region - city).
  • date: start and end dates.

…and the output:

  • covid19plot: plotly output that will render an interactive plot.

Wrap everything into a fluidPage:

# Define UI for application
ui <- fluidPage(
    selectInput("country", label = "Country", multiple = TRUE, choices = unique(covid19()$administrative_area_level_1), selected = "Italy"),
    selectInput("type", label = "type", choices = c("confirmed", "tests", "recovered", "deaths")),
    selectInput("level", label = "Granularity", choices = c("Country" = 1, "Region" = 2, "City" = 3), selected = 2),
    dateRangeInput("date", label = "Date", start = "2020-01-01"),

Server logic

After defining the reactive inputs in the UI, we connect such inputs to the covid19() function to fetch the data. The following code snippet shows how to render an interactive plot(ly) that automatically updates when any of the input is changed. Note that the covid19() function uses an internal memory caching system so that the data are never downloaded twice. Calling the function multiple times is highly efficient and user friendly.

# Define server logic
server <- function(input, output) {

    output$covid19plot <- renderPlotly({
            x <- covid19(country = input$country, level = input$level, start = input$date[1], end = input$date[2])
            color <- paste0("administrative_area_level_", input$level)
            plot_ly(x = x[["date"]], y = x[[input$type]], color = x[[color]])

Run the application

The sample application is available at

# Run the application 
shinyApp(ui = ui, server = server)

Final remarks

We built a simple application interfacing Shiny with the R package COVID19, representing a general architecture that invite re-use. The sample app may be used as building block for more advanced COVID-19 data-driven applications. In particular, the dataset available via the covid19() function includes additional metrics about COVID-19 cases, policy measures, geographic information, and external keys that allow to easily extend the dataset with World Bank Open Data, Google Mobility Reports, Apple Mobility Reports, and local governmental data. See the full dataset documentation and the COVID19 code snippets.

[1] Guidotti, E., Ardia, D., (2020). COVID-19 Data Hub, Journal of Open Source Software, 5(51):2376