Data Frame

Row

Comparison between the columns

Data representation Using Graphs

Row

Chart (3): Cumulative Cases Over Time

Chart (4): Correlation Between Numeric Fields

New Dataset

Row

Country-wise Summary

Monthly Summary

Row

Top 10 Countries

Region Summary

Covid 19 Analysis

Row

Total Cases

779,268,246

Total Deaths

7,116,051

Countries Reporting

240

Date Range Covered

Jan 2020 - Jul 2026

Row

Global Daily New Cases Trend

Top 10 Countries by Cumulative Cases

Row

WHO Region-wise Case Distribution

Case Fatality Rate (CFR) by Region

---
title: "Professional"
author: "Sunita"
output: 
  flexdashboard::flex_dashboard:
    orientation: rows
    social: menu
    source_code: embed
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE, warning = FALSE, message = FALSE)

library(flexdashboard)
library(dplyr)
library(ggplot2)
library(plotly)
library(DT)
library(data.table)
library(scales)

# ---------------------------------------------------------------------
# DATA DICTIONARY - WHO COVID-19 Global Daily Data
# (11 fields, ~573,000 rows, one row per country per reporting day)
# ---------------------------------------------------------------------
# Date_reported      : date the figures were reported, format M/D/YYYY (chr)
# Country_code       : ISO-2 country code, some rows blank (chr)
# Country            : country / territory name, 240 unique values (chr)
# WHO_region         : AFR, AMR, EMR, EUR, SEAR, WPR, OTHER (chr)
# New_cases          : new confirmed cases that day, has NAs (num)
# Cumulative_cases   : running total of confirmed cases (int)
# New_deaths         : new deaths that day, has NAs (num)
# Cumulative_deaths  : running total of deaths (int)
# year               : year extracted from Date_reported (int)
#                       (raw column header has a leading space - cleaned below)
# month              : month abbreviation extracted from Date_reported, "Jan"-"Dec" (chr)
# date               : day-of-month extracted from Date_reported (int)
# ---------------------------------------------------------------------

# fread() is much faster than read.csv() for a ~570k row / 32MB file
covid <- fread("WHO-COVID-19-global-daily-data.csv")

# raw header has a stray leading space before "year" - strip whitespace from all names
setnames(covid, old = names(covid), new = trimws(names(covid)))

# parse Date_reported as a real Date so it sorts/plots correctly
covid <- covid %>%
  mutate(Date_reported = as.Date(Date_reported, format = "%m/%d/%Y"))
```

Data Frame
=======================================================================

Row
-----------------------------------------------------------------------

### Comparison between the columns

```{r}
# Fields: WHO_region, New_cases
# Query: aggregate total New_cases by WHO_region, then plot as an interactive bar chart
region_totals <- covid %>%
  group_by(WHO_region) %>%
  summarise(Total_New_Cases = sum(New_cases, na.rm = TRUE), .groups = "drop") %>%
  arrange(desc(Total_New_Cases))

p <- ggplot(
  region_totals,
  aes(
    x = reorder(WHO_region, -Total_New_Cases), y = Total_New_Cases,
    text = paste0("Region: ", WHO_region, "<br>Total New Cases: ", comma(Total_New_Cases))
  )
) +
  geom_col(fill = "steelblue") +
  labs(title = "Total New Cases by WHO Region", x = NULL, y = "Total New Cases") +
  theme_minimal()

ggplotly(p, tooltip = "text") %>% layout(hovermode = "closest")
```

### Data representation Using Graphs

```{r}
# Fields: New_cases
# Query: drop NA / zero-report rows, then plot an interactive density curve
dens_df <- covid %>% filter(!is.na(New_cases), New_cases > 0)

p <- ggplot(dens_df, aes(x = New_cases)) +
  geom_density(fill = "darkred", color = "darkred", alpha = 0.4) +
  labs(title = "Density Plot of Daily New Cases", x = "New Cases (per country, per day)", y = "Density") +
  theme_minimal()

# hovering shows the exact New Cases value (x) and density (y) at that point
ggplotly(p, tooltip = c("x", "y")) %>% layout(hovermode = "closest")
```

Row
-----------------------------------------------------------------------

### Chart (3): Cumulative Cases Over Time

```{r}
# Fields: Date_reported, Cumulative_cases, Country
# Query: filter(Country == "...") then ggplot(aes(Date_reported, Cumulative_cases)) + geom_line()
# swap "India" for any value from the Country field
p <- covid %>%
  filter(Country == "India") %>%
  ggplot(aes(
    x = Date_reported, y = Cumulative_cases,
    text = paste0("Date: ", format(Date_reported, "%d %b %Y"), "<br>Cumulative Cases: ", comma(Cumulative_cases))
  )) +
  geom_line(color = "darkblue", size = 1) +
  labs(title = "Cumulative Cases Over Time - India", x = "Date", y = "Cumulative Cases") +
  theme_minimal()

ggplotly(p, tooltip = "text") %>% layout(hovermode = "x unified")
```

### Chart (4): Correlation Between Numeric Fields

```{r}
# Fields: New_cases, Cumulative_cases, New_deaths, Cumulative_deaths
# Query: cor() on the four numeric fields, then plot as an interactive heatmap
numeric_df <- covid %>%
  select(New_cases, Cumulative_cases, New_deaths, Cumulative_deaths)

correlation <- cor(numeric_df, use = "complete.obs")
field_names <- colnames(correlation)

# build a matching matrix of hover text: "FieldA vs FieldB / Correlation: 0.xx"
pair_labels <- outer(field_names, field_names, FUN = function(a, b) paste0(a, " vs ", b, "<br>Correlation: "))
hover_text <- matrix(paste0(pair_labels, round(correlation, 2)), nrow = nrow(correlation), dimnames = dimnames(correlation))

plot_ly(
  x = field_names, y = field_names, z = correlation,
  type = "heatmap",
  colors = colorRampPalette(c("firebrick", "white", "steelblue"))(100),
  zmin = -1, zmax = 1,
  text = hover_text, hoverinfo = "text"
) %>%
  layout(title = "Correlation Between Numeric Fields") %>%
  add_annotations(
    x = rep(field_names, each = length(field_names)),
    y = rep(field_names, times = length(field_names)),
    text = round(as.vector(correlation), 2),
    showarrow = FALSE,
    font = list(color = "black", size = 12)
  )
```

New Dataset
=======================================================================

Row
-----------------------------------------------------------------------

### Country-wise Summary

```{r}
# Fields: Country, WHO_region, New_cases, New_deaths
# Query: group_by(Country, WHO_region) %>% summarise(Total_Cases = sum(New_cases), Total_Deaths = sum(New_deaths))
country_summary <- covid %>%
  group_by(Country, WHO_region) %>%
  summarise(
    Total_Cases  = sum(New_cases, na.rm = TRUE),
    Total_Deaths = sum(New_deaths, na.rm = TRUE),
    .groups = "drop"
  ) %>%
  mutate(CFR_Percent = round(ifelse(Total_Cases > 0, Total_Deaths / Total_Cases * 100, 0), 2)) %>%
  arrange(desc(Total_Cases))

datatable(country_summary, options = list(pageLength = 6), rownames = FALSE)
```

### Monthly Summary

```{r}
# Fields: year, month, New_cases, New_deaths
# Query: group_by(year, month) %>% summarise(...)
monthly_summary <- covid %>%
  group_by(year, month) %>%
  summarise(
    Total_Cases  = sum(New_cases, na.rm = TRUE),
    Total_Deaths = sum(New_deaths, na.rm = TRUE),
    .groups = "drop"
  ) %>%
  mutate(month = factor(month, levels = month.abb)) %>%
  arrange(year, month)

datatable(monthly_summary, options = list(pageLength = 6), rownames = FALSE)
```

Row
-----------------------------------------------------------------------

### Top 10 Countries

```{r}
# Fields: Country, Date_reported, Cumulative_cases
# Query: keep each country's row at its latest Date_reported, arrange(desc(Cumulative_cases)) %>% head(10)
top10 <- covid %>%
  group_by(Country) %>%
  filter(Date_reported == max(Date_reported)) %>%
  ungroup() %>%
  select(Country, Cumulative_cases) %>%
  arrange(desc(Cumulative_cases)) %>%
  head(10)

datatable(top10, options = list(pageLength = 10, dom = 't'), rownames = FALSE)
```

### Region Summary

```{r}
# Fields: WHO_region, New_cases, New_deaths
# Query: group_by(WHO_region) %>% summarise(...)
region_summary <- covid %>%
  group_by(WHO_region) %>%
  summarise(
    Total_Cases  = sum(New_cases, na.rm = TRUE),
    Total_Deaths = sum(New_deaths, na.rm = TRUE),
    .groups = "drop"
  ) %>%
  mutate(CFR_Percent = round(Total_Deaths / Total_Cases * 100, 2)) %>%
  arrange(desc(Total_Cases))

datatable(region_summary, options = list(pageLength = 7, dom = 't'), rownames = FALSE)
```

Covid 19 Analysis
=======================================================================

Row {data-height=120}
-----------------------------------------------------------------------

### Total Cases

```{r}
valueBox(comma(sum(covid$New_cases, na.rm = TRUE)), icon = "fa-heartbeat", color = "warning")
```

### Total Deaths

```{r}
valueBox(comma(sum(covid$New_deaths, na.rm = TRUE)), icon = "fa-exclamation-triangle", color = "danger")
```

### Countries Reporting

```{r}
valueBox(n_distinct(covid$Country), icon = "fa-globe", color = "info")
```

### Date Range Covered

```{r}
valueBox(
  paste0(format(min(covid$Date_reported), "%b %Y"), " - ", format(max(covid$Date_reported), "%b %Y")),
  icon = "fa-calendar",
  color = "primary"
)
```

Row
-----------------------------------------------------------------------

### Global Daily New Cases Trend

```{r}
# Fields: Date_reported, New_cases
# Query: aggregate New_cases across all countries by Date_reported, then line chart
global_daily <- covid %>%
  group_by(Date_reported) %>%
  summarise(Total_New_Cases = sum(New_cases, na.rm = TRUE), .groups = "drop")

p <- ggplot(global_daily, aes(
  x = Date_reported, y = Total_New_Cases,
  text = paste0("Date: ", format(Date_reported, "%d %b %Y"), "<br>Global New Cases: ", comma(Total_New_Cases))
)) +
  geom_line(color = "steelblue", size = 0.6) +
  labs(title = "Global Daily New Cases", x = "Date", y = "New Cases") +
  theme_minimal()

ggplotly(p, tooltip = "text") %>% layout(hovermode = "x unified")
```

### Top 10 Countries by Cumulative Cases

```{r}
# Fields: Country, Date_reported, Cumulative_cases
# Query: same logic as the "Top 10 Countries" tab, plotted with geom_col()
top10_plot <- covid %>%
  group_by(Country) %>%
  filter(Date_reported == max(Date_reported)) %>%
  ungroup() %>%
  select(Country, Cumulative_cases) %>%
  arrange(desc(Cumulative_cases)) %>%
  head(10)

p <- ggplot(top10_plot, aes(
  x = reorder(Country, Cumulative_cases), y = Cumulative_cases,
  text = paste0("Country: ", Country, "<br>Cumulative Cases: ", comma(Cumulative_cases))
)) +
  geom_col(fill = "darkorange") +
  coord_flip() +
  labs(title = "Top 10 Countries by Cumulative Cases", x = NULL, y = "Cumulative Cases") +
  theme_minimal()

ggplotly(p, tooltip = "text") %>% layout(hovermode = "closest")
```

Row
-----------------------------------------------------------------------

### WHO Region-wise Case Distribution

```{r}
# Fields: WHO_region, New_cases
# Query: group_by(WHO_region) %>% summarise(sum(New_cases)), plot as donut/pie
region_share <- covid %>%
  group_by(WHO_region) %>%
  summarise(Total_Cases = sum(New_cases, na.rm = TRUE), .groups = "drop")

# native plotly pie: hovering shows the region name, exact case count, and % share automatically
plot_ly(
  region_share,
  labels = ~WHO_region, values = ~Total_Cases, type = "pie",
  textinfo = "label+percent",
  hovertemplate = "Region: %{label}<br>Total Cases: %{value:,}<br>Share: %{percent}<extra></extra>"
) %>%
  layout(title = "Share of Total Cases by WHO Region")
```

### Case Fatality Rate (CFR) by Region

```{r}
# Fields: WHO_region, New_cases, New_deaths
# Query: Total_Deaths / Total_Cases * 100 per region
region_cfr <- covid %>%
  group_by(WHO_region) %>%
  summarise(
    Total_Cases  = sum(New_cases, na.rm = TRUE),
    Total_Deaths = sum(New_deaths, na.rm = TRUE),
    .groups = "drop"
  ) %>%
  mutate(CFR_Percent = round(Total_Deaths / Total_Cases * 100, 2))

p <- ggplot(region_cfr, aes(
  x = reorder(WHO_region, CFR_Percent), y = CFR_Percent,
  text = paste0("Region: ", WHO_region, "<br>Case Fatality Rate: ", CFR_Percent, "%")
)) +
  geom_col(fill = "firebrick") +
  coord_flip() +
  labs(title = "Case Fatality Rate by WHO Region", x = NULL, y = "CFR (%)") +
  theme_minimal()

ggplotly(p, tooltip = "text") %>% layout(hovermode = "closest")
```