This dashboard summarizes COVID-19 in the Greater caribbean Islands Region by aggregating daily New_Cases from coronatsCarib_F.csv into ISO weekly totals (weeks start Monday) for each country, making cross-country trends easier to compare.
What’s inside - Overview: Latest-week total, top country, and number of countries. - Weekly table: Filterable, exportable weekly counts by country and week. - Pivot heatmap: Country × month view to spot periods of higher transmission. - Trend chart: Stacked weekly time series showing each country’s contribution.
How to use - Filter by country/month in the sidebar; hover bars for exact values; export tables as needed.
Notes - Weekly values are sums of daily New_Cases (blanks treated as 0); recent weeks may be incomplete due to reporting lag.
---
title: "COVID-19 in the Greater Caribbean Islands Region"
output:
flexdashboard::flex_dashboard:
orientation: rows
vertical_layout: fill
theme: flatly
source_code: embed
css: styles.css
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE, warning = TRUE, message = TRUE)
suppressPackageStartupMessages({
library(tidyverse)
library(lubridate)
library(crosstalk)
library(DT)
library(plotly)
library(rpivotTable)
library(scales)
library(ggsci)
# library(flexdashboard) # not required since we namespace valueBox
})
# Lancet-inspired palettes
lancet_pal <- ggsci::pal_lancet()(9)
# Sequential medical blues for heatmaps
lancet_heat <- c("#F7FBFF", "#DEEBF7", "#C6DBEF", "#9ECAE1", "#6BAED6", "#4292C6", "#2171B5", "#08519C")
# Read data (blanks -> 0, parse dates)
# Read data (blanks -> 0, parse dates)
cases_raw <- readr::read_csv(
"00_data/coronatsCarib_F.csv",
col_types = readr::cols(
Country = readr::col_character(),
date = readr::col_date(),
New_Cases_N = readr::col_double(),
New_Cases = readr::col_double()
)
) %>%
filter (date < "2021-10-25")
# Aggregate to weekly cases by Country
weekly_data <- cases_raw %>%
mutate(
New_Cases = coalesce(New_Cases, 0),
week_start = floor_date(date, unit = "week", week_start = 1),
year_week = strftime(week_start, "%G-W%V"),
year_month = format(week_start, "%Y-%m")
) %>%
group_by(Country, week_start, year_week, year_month) %>%
summarise(cases = sum(New_Cases, na.rm = TRUE), .groups = "drop") %>%
arrange(desc(week_start)) # sort BEFORE wrapping in SharedData
# Crosstalk wrapper
weekly_shared <- SharedData$new(weekly_data)
# KPIs
latest_week <- suppressWarnings(max(weekly_data$week_start, na.rm = TRUE))
latest_total <- weekly_data %>%
filter(week_start == latest_week) %>%
summarise(total = sum(cases, na.rm = TRUE)) %>%
pull(total) %>% { if (length(.) == 0 || is.na(.)) 0 else . }
top_country_latest <- weekly_data %>%
filter(week_start == latest_week) %>%
slice_max(cases, n = 1, with_ties = FALSE)
kpi_top_country <- if (nrow(top_country_latest)) top_country_latest$Country else NA_character_
kpi_top_country_cases <- if (nrow(top_country_latest)) top_country_latest$cases else 0
```
Overview
=======================================================================
Row {data-height=140}
-----------------------------------------------------------------------
### Latest week total
```{r}
flexdashboard::valueBox(
value = scales::comma(latest_total),
caption = paste0(
"Total New Cases (week of ",
ifelse(is.finite(latest_week), format(latest_week, "%Y-%m-%d"), "N/A"),
")"
),
icon = "fa-line-chart",
color = if (is.finite(latest_total) && latest_total > 0) "primary" else "success"
)
```
### Top country (latest week)
```{r}
flexdashboard::valueBox(
value = ifelse(is.na(kpi_top_country), "N/A", kpi_top_country),
caption = paste0("Highest weekly cases: ", scales::comma(kpi_top_country_cases)),
icon = "fa-flag",
color = "info"
)
```
### Countries covered
```{r}
flexdashboard::valueBox(
value = dplyr::n_distinct(weekly_data$Country),
caption = "Unique countries",
icon = "fa-globe",
color = "success"
)
```
Row {data-height=220}
-----------------------------------------------------------------------
### About this dashboard
This dashboard summarizes COVID-19 in the Greater caribbean Islands Region by aggregating daily New_Cases from coronatsCarib_F.csv into ISO weekly totals (weeks start Monday) for each country, making cross-country trends easier to compare.
What’s inside
- Overview: Latest-week total, top country, and number of countries.
- Weekly table: Filterable, exportable weekly counts by country and week.
- Pivot heatmap: Country × month view to spot periods of higher transmission.
- Trend chart: Stacked weekly time series showing each country’s contribution.
How to use
- Filter by country/month in the sidebar; hover bars for exact values; export tables as needed.
Notes
- Weekly values are sums of daily New_Cases (blanks treated as 0); recent weeks may be incomplete due to reporting lag.
Weekly New Cases by Country (Table)
=======================================================================
Inputs {.sidebar}
-----------------------------------------------------------------------
```{r}
filter_checkbox("cty", "Choose country", weekly_shared, ~Country)
filter_select("ym", "Choose month", weekly_shared, ~year_month)
filter_slider("wk_cases", "Filter weekly cases", weekly_shared, ~cases, width = "100%")
```
Row
-----------------------------------------------------------------------
### Weekly New Cases (table)
```{r}
DT::datatable(
weekly_shared,
class = "compact cell-border stripe",
rownames = FALSE,
extensions = c("Buttons", "Responsive"),
options = list(
dom = "Bfrtip",
buttons = c("copy", "csv", "excel", "print"),
pageLength = 20,
autoWidth = TRUE
)
)
```
Weekly New Cases by Country (Pivot)
=======================================================================
Row
-----------------------------------------------------------------------
### Interactive pivot (sum of weekly cases)
```{r}
rpivotTable(
data = weekly_data,
rows = "Country",
cols = "year_month",
vals = "cases",
aggregatorName = "Sum",
rendererName = "Heatmap",
rendererOptions = list(
colorScale = list(colors = lancet_heat)
),
width = "100%", height = "600px"
)
```
Weekly New Cases by Country (Trend)
=======================================================================
Inputs {.sidebar}
-----------------------------------------------------------------------
```{r}
filter_checkbox("cty2", "Choose country", weekly_shared, ~Country)
filter_select("ym2", "Choose month", weekly_shared, ~year_month)
```
Row
-----------------------------------------------------------------------
### Weekly trend (stacked, Lancet palette)
```{r}
plot_ly(
data = weekly_shared,
x = ~week_start, y = ~cases,
type = "bar",
color = ~Country,
colors = lancet_pal,
hoverinfo = "text",
text = ~paste0(
"Country: ", Country,
"<br>Week start: ", format(week_start, "%Y-%m-%d"),
"<br>Cases: ", scales::comma(cases)
)
) %>%
layout(
barmode = "stack",
legend = list(orientation = "h"),
xaxis = list(title = "Week start"),
yaxis = list(title = "Weekly New Cases", rangemode = "tozero")
)
```