Statistics for the COVID-19 outbreak in Sweden

This page provides plots and visualisations of currently available statistics for the novel coronavirus (COVID-19) outbreak in Sweden.

This page is largely the result of a personal exercise in data analysis but since it received some interest on Twitter, I have set this page to automatically update every day following the daily updates of the national statistics from Sweden's Public Health Authority (Folkhälsomyndigheten).

The data presented here is scraped from a publicly available source (c19.se), and I am not responsible for the accuracy of these numbers. The code used to produce the images on this page is provided below if you would like to reproduce these or see how it is done.

Confirmed cases and deaths in Sweden, last 30 days

Confirmed cases and deaths in Sweden, last 30 days

Rolling 7-day change in cases and deaths in Sweden, last 30 days

Confirmed cases and death by county, last 30 days

Confirmed cases by county, last 30 days

Deaths by county, last 30 days

Current statistics by county, per 100,000 inhabitants

Confirmed cases per 100k inhabitants, by county

Deaths per 100k inhabitants, by county

Hospitalisations per 100k inhabitants, by county

ICU admissions per 100k inhabitants, by county

Change in cases/deaths by county

The plots below shows the increase in the number of confirmed cases/deaths over the last seven days.

Increase in cases by county, last 7 days

Increase in cases by county, last 7 days (bar chart)

Increase in deaths by county, last 7 days

Increase in deaths by county, last 7 days (bar chart)

The plots below show the rolling percentage change in the number of new cases and deaths over the preceding seven days.

Rolling 7-day change in cases, last 30 days

Rolling 7-day change in deaths, last 30 days

Code

Below is the code, written in R, used to scrape the data from the web and produce the above images.

The geoJSON shapefile used to produce the choropleth maps was downloaded from here and re-hosted at this site for convenience.

# load necessary packages
library(rvest)
library(tidyverse)
library(viridis)
library(geojsonio)
library(ggrepel)
library(broom)
library(lubridate)

# set the working directory
# setwd("/path/to/working/directory")

### 1. Importing map data ###

# Read in geoJSON shapefile and convert to dataframe
spdf <- geojson_read("http://lacey.se/dl/sweden.geojson", what = "sp") %>% tidy

# Need to match 'id' in the shapefile to the name of the county,
# so we make a dataframe of ids and county names
map_ids <- data.frame(
  id = c(1:21),
  county = c("Stockholm", "Västmanland", "Värmland", "Örebro", "Jämtland", "Blekinge",
             "Uppsala", "Sörmland", "Östergötland", "Gotland", "Jönköping", "Kronoberg",
             "Västernorrland", "Kalmar", "Skåne", "Halland", "Gävleborg", "Västra Götaland",
             "Dalarna", "Västerbotten", "Norrbotten")
)

# Make the new map dataframe by merging the two.
map_tidy <- merge(spdf, map_ids)

### List of counties and their population ###
# Need table of counties and populations for recalculating on population basis.
# 2018 population data taken directly from Statista

# Create the dataframe
counties <- data.frame(
  county = c("Stockholm", "Västmanland", "Värmland", "Örebro", "Jämtland", "Blekinge",
             "Uppsala", "Sörmland", "Östergötland", "Gotland", "Jönköping", "Kronoberg",
             "Västernorrland", "Kalmar", "Skåne", "Halland", "Gävleborg", "Västra Götaland",
             "Dalarna", "Västerbotten", "Norrbotten"),
  pop = c(2344124, 273929, 281482, 302252, 130280, 159684, 376354, 294695, 461583, 59249,
          360825, 199886, 245453, 244670, 1362164, 329352, 286547, 1709814, 287191, 270154,
          250497)
)

### Scraping data from c19.se. ###
# Scrape the data as needed and then reformat where necessary

# Scrape data for the latest day only, from the homepage.
# Find the relevant table, rename columns, merge with the counties dataframe
# and calculate population-level data by county
c19se_today <- "https://c19.se" %>%
  read_html() %>%
  html_nodes(xpath='/html/body/div/main/section/div/div[1]/table') %>%
  html_table() %>%
  .[[1]] %>%
  slice(1:n()-1) %>%
  rename(county = Region, cases = Fall, casestoday = `Fall idag`, hospital = `På sjukhus`, icu = `På IVA`,
         deaths = `Döda`) %>%
  merge(counties, by = "county") %>%
  mutate(cases_norm = 1E5 * cases / pop, deaths_norm = 1E5 * deaths / pop,
         hospital_norm = 1E5 * hospital / pop, icu_norm = 1E5 * icu / pop)

# Scrape pages for individual regions. Looks through the sub-page for each region,
# takes the relevant data, combines, renames and processes as desired.
# c19.se only shows data for the last 30 days, so at the last step the numbers of
# cases and deaths are shifted according to the number of cases/deaths which had
# been reported prior to the first date in the individual tables.
c19se <- lapply(counties$county, function(county) {
  paste("https://c19.se/Sweden/", county, sep = "") %>%
    read_html() %>%
    html_nodes(xpath = '/html/body/div/main/section/div/div/table') %>%
    html_table() %>%
    .[[1]] %>%
    slice(1:n()-1) %>%
    rename(day = Dag, cases = Fall, deaths = Döda) %>%
    mutate(county = county)
}) %>%
  do.call(rbind, .) %>%
  merge(counties, by = "county") %>%
  mutate(day = as.Date(day, format = "%b %d")) %>%
  arrange(county, day) %>%
  group_by(county) %>%
  mutate(cum_cases = cumsum(cases), cum_deaths = cumsum(deaths),
         cum_cases = cum_cases + c19se_today$cases[c19se_today$county == last(county)] - last(cum_cases),
         cum_deaths = cum_deaths + c19se_today$deaths[c19se_today$county == last(county)] - last(cum_deaths),
         cum_cases_norm = 1E5 * cum_cases / pop, cum_deaths_norm = 1E5 * cum_deaths / pop)

### Combine with map data and plot

# Create dataframe to plot choropleth maps by merging statistics with map data
c19se_today_map <- c19se_today %>%
  merge(map_tidy, by = "county") %>%
  arrange(order, group)

# For indicating cities, need to create tables of cities with their geographical
# coordinates. We'll take the three largest cities in Sweden and a random selection
# of smaller cities/towns to keep the maps interesting. First create the table for big
# cities
bigcities <- structure(list(city = structure(c(3L, 1L, 2L), .Label = c("Göteborg",
                                                                       "Malmö", "Stockholm"), class = "factor"), lat = c(59.3293, 57.7089,
                                                                                                                         55.605), long = c(18.0686, 11.9746, 13.0038)), class = "data.frame", row.names = c(NA,
                                                                                                                                                                                                            -3L))
# Then equivalent table for 51 smaller towns/cities
cities2 <- structure(list(city = structure(c(47L, 46L, 49L, 32L, 26L, 15L,
                                             18L, 30L, 28L, 45L, 11L, 5L, 38L, 7L, 12L, 50L, 21L, 40L, 34L,
                                             43L, 27L, 6L, 23L, 19L, 37L, 31L, 20L, 44L, 36L, 48L, 24L, 33L,
                                             2L, 17L, 22L, 13L, 1L, 29L, 9L, 14L, 25L, 16L, 51L, 8L, 4L, 10L,
                                             41L, 3L, 35L, 39L, 42L), .Label = c("Abisko", "Åre", "Arvika",
                                                                                 "Boden", "Borås", "Borlänge", "Eskilstuna", "Falun", "Flen",
                                                                                 "Gällivare", "Gävle", "Halmstad", "Haparanda", "Härnösand",
                                                                                 "Helsingborg", "Hudiksvall", "Jokkmokk", "Jönköping", "Kalmar",
                                                                                 "Karlskrona", "Karlstad", "Kiruna", "Kristianstad", "Landskrona",
                                                                                 "Leksand", "Linköping", "Luleå", "Lund", "Mora", "Norrköping",
                                                                                 "Nyköping", "Örebro", "Örnsköldsvik", "Östersund", "Sälen",
                                                                                 "Skellefteå", "Skövde", "Södertälje", "Storuman", "Sundsvall",
                                                                                 "Sveg", "Tärnaby", "Trollhättan", "Uddevalla", "Umeå", "Upplands Väsby",
                                                                                 "Uppsala", "Varberg", "Västerås", "Växjö", "Visby"), class = "factor"),
                          lat = c(59.8586, 59.5196, 59.6099, 59.2753, 58.4108, 56.0465,
                                  57.7826, 58.5877, 55.7047, 63.8258, 60.6749, 57.721, 59.1954,
                                  59.3712, 56.6744, 56.879, 59.4022, 62.3908, 63.1767, 58.2835,
                                  65.5848, 60.4843, 56.0294, 56.6634, 58.3903, 58.7528, 56.1612,
                                  58.3498, 64.7502, 57.1071, 55.8703, 63.29, 63.399, 66.607,
                                  67.8558, 65.8417, 68.3495, 61.0049, 59.0579, 62.6323, 60.7303,
                                  61.7274, 57.6348, 60.6065, 65.8251, 67.1379, 62.0346, 59.6549,
                                  61.1614, 65.0956, 65.71), long = c(17.6389, 17.9283, 16.5448,
                                                                     15.2134, 15.6214, 12.6945, 14.1618, 16.1924, 13.191, 20.263,
                                                                     17.1413, 12.9398, 17.6257, 16.5098, 12.8578, 14.8059, 13.5115,
                                                                     17.3069, 14.6361, 12.2858, 22.1567, 15.434, 14.1567, 16.3568,
                                                                     13.8461, 17.0092, 15.5869, 11.9356, 20.9509, 12.2521, 12.8301,
                                                                     18.7166, 13.0815, 19.8229, 20.2253, 24.1277, 18.8312, 14.537,
                                                                     16.5879, 17.9409, 14.9999, 17.1074, 18.2948, 15.6355, 21.6887,
                                                                     20.6594, 14.359, 12.5921, 13.263, 17.1123, 15.268)), class = "data.frame", row.names = c(NA,
                                                                                                                                                              -51L))

### Create images

# Confirmed cases per 100k.
# First randomly generate table of cities/towns to mark on the map.
# Using set.seed hopefully ensures different selection of cities every day.
set.seed(day(Sys.Date()) + 1)
cities_sample <- sample_n(cities2, 4) %>%
  rbind(bigcities)

# Create choropleth map
ggplot(c19se_today_map) +
  geom_polygon(aes(x = long, y = lat, group = group, fill = cases_norm), color = "black") +
  geom_polygon(data = filter(map_tidy, group %in% c(5.2, 19.2, 21.2)),
               aes(x = long, y = lat, group = group), fill = "white", color = "black") +
  geom_point(data = cities_sample, aes(x = long, y = lat), shape = 21, fill = "red", size = 2, stroke = 0.8, alpha = 0.7) +
  geom_label_repel(data = cities_sample, aes(x = long, y = lat, label = city),
                            force = 3, box.padding = unit(0.35, "lines"), size = 3,
                            alpha = 0.6, seed = 1234) +
  geom_label_repel(data = cities_sample, aes(x = long, y = lat, label = city),
                            force = 3, box.padding = unit(0.35, "lines"), size = 3,
                            alpha = 1, fill = NA, seed = 1234) +
  coord_map() +
  scale_fill_viridis("", limits = c(0, NA)) +
  theme_void() +
  labs(title = "COVID-19 in Sweden",
       subtitle = paste("Confirmed cases per 100,000 inhabitants\ndata: c19.se, fetched ", last(c19se$day), sep = ""))

# Save
ggsave("cases_per_100k.png", width = 6.5, height = 6.5, units = "in", dpi = 300)

# Deaths per 100k
# Maps below are created using the same method as above
set.seed(day(Sys.Date()) + 2)
cities_sample <- sample_n(cities2, 4) %>%
  rbind(bigcities)

ggplot(c19se_today_map) +
  geom_polygon(aes(x = long, y = lat, group = group, fill = deaths_norm), color = "black") +
  geom_polygon(data = filter(map_tidy, group %in% c(5.2, 19.2, 21.2)),
               aes(x = long, y = lat, group = group), fill = "white", color = "black") +
  geom_point(data = cities_sample, aes(x = long, y = lat), shape = 21, fill = "red", size = 2, stroke = 0.8, alpha = 0.7) +
  geom_label_repel(data = cities_sample, aes(x = long, y = lat, label = city),
                   force = 3, box.padding = unit(0.35, "lines"), size = 3,
                   alpha = 0.6, seed = 1234) +
  geom_label_repel(data = cities_sample, aes(x = long, y = lat, label = city),
                   force = 3, box.padding = unit(0.35, "lines"), size = 3,
                   alpha = 1, fill = NA, seed = 1234) +
  coord_map() +
  scale_fill_viridis("", limits = c(0, NA)) +
  theme_void() +
  labs(title = "COVID-19 in Sweden",
       subtitle = paste("Deaths per 100,000 inhabitants\ndata: c19.se, fetched ", last(c19se$day), sep = ""))

ggsave("deaths_per_100k.png", width = 6.5, height = 6.5, units = "in", dpi = 300)

# Hospitalisations per 100k
set.seed(day(Sys.Date()) + 3)
cities_sample <- sample_n(cities2, 4) %>%
  rbind(bigcities)

ggplot(c19se_today_map) +
  geom_polygon(aes(x = long, y = lat, group = group, fill = hospital_norm), color = "black") +
  geom_polygon(data = filter(map_tidy, group %in% c(5.2, 19.2, 21.2)),
               aes(x = long, y = lat, group = group), fill = "white", color = "black") +
  geom_point(data = cities_sample, aes(x = long, y = lat), shape = 21, fill = "red", size = 2, stroke = 0.8, alpha = 0.7) +
  geom_label_repel(data = cities_sample, aes(x = long, y = lat, label = city),
                   force = 3, box.padding = unit(0.35, "lines"), size = 3,
                   alpha = 0.6, seed = 1234) +
  geom_label_repel(data = cities_sample, aes(x = long, y = lat, label = city),
                   force = 3, box.padding = unit(0.35, "lines"), size = 3,
                   alpha = 1, fill = NA, seed = 1234) +
  coord_map() +
  scale_fill_viridis("", limits = c(0, NA)) +
  theme_void() +
  labs(title = "COVID-19 in Sweden",
       subtitle = paste("Hospitalisations per 100,000 inhabitants\ndata: c19.se, fetched ", last(c19se$day), sep = ""))

ggsave("hospitalisations_per_100k.png", width = 6.5, height = 6.5, units = "in", dpi = 300)

# ICU per 100k
set.seed(day(Sys.Date()) + 4)
cities_sample <- sample_n(cities2, 4) %>%
  rbind(bigcities)

ggplot(c19se_today_map) +
  geom_polygon(aes(x = long, y = lat, group = group, fill = icu_norm), color = "black") +
  geom_polygon(data = filter(map_tidy, group %in% c(5.2, 19.2, 21.2)),
               aes(x = long, y = lat, group = group), fill = "white", color = "black") +
  geom_point(data = cities_sample, aes(x = long, y = lat), shape = 21, fill = "red", size = 2, stroke = 0.8, alpha = 0.7) +
  geom_label_repel(data = cities_sample, aes(x = long, y = lat, label = city),
                   force = 3, box.padding = unit(0.35, "lines"), size = 3,
                   alpha = 0.6, seed = 1234) +
  geom_label_repel(data = cities_sample, aes(x = long, y = lat, label = city),
                   force = 3, box.padding = unit(0.35, "lines"), size = 3,
                   alpha = 1, fill = NA, seed = 1234) +
  coord_map() +
  scale_fill_viridis("", limits = c(0, NA)) +
  theme_void() +
  labs(title = "COVID-19 in Sweden",
       subtitle = paste("ICU admissions per 100,000 inhabitants\ndata: c19.se, fetched ", last(c19se$day), sep = ""))

ggsave("icu_per_100k.png", width = 6.5, height = 6.5, units = "in", dpi = 300)


### Regional trends

# Take day-resolved regional data and calculate the percentage increase in cases/deaths
# over the last 7 days. Also take the first and last values used for each statistic,
# for plotting purposes later.
c19se_incr <- c19se %>%
  group_by(county) %>%
  filter(day %in% c(last(day), last(day) - 7)) %>%
  summarise(incr_cases = (last(cum_cases) - first(cum_cases)) / first(cum_cases),
            incr_deaths = (last(cum_deaths) - first(cum_deaths)) / first(cum_deaths),
            cases_first = first(cum_cases), death_first = first(cum_deaths),
            cases_last = last(cum_cases), death_last = last(cum_deaths))

# Merge this with the map data to create choropleths
c19se_incr_map <- merge(c19se_incr, map_tidy, by = "county") %>%
  arrange(order)

# Create choropleth map. Increase in confirmed cases last 7 days
set.seed(day(Sys.Date()) + 5)
cities_sample <- sample_n(cities2, 3) %>%
  rbind(bigcities)

ggplot(c19se_incr_map) +
  geom_polygon(aes(x = long, y = lat, group = group, fill = incr_cases * 100), color = "black") +
  geom_polygon(data = filter(map_tidy, group %in% c(5.2, 19.2, 21.2)),
               aes(x = long, y = lat, group = group), fill = "white", color = "black") +
  geom_point(data = cities_sample, aes(x = long, y = lat), shape = 21, fill = "red", size = 2, stroke = 0.8, alpha = 0.7) +
  geom_label_repel(data = cities_sample, aes(x = long, y = lat, label = city),
                   force = 3, box.padding = unit(0.35, "lines"), size = 3,
                   alpha = 0.6, seed = 1234) +
  geom_label_repel(data = cities_sample, aes(x = long, y = lat, label = city),
                   force = 3, box.padding = unit(0.35, "lines"), size = 3,
                   alpha = 1, fill = NA, seed = 1234) +
  coord_map() +
  scale_fill_viridis("", limits = c(0, NA)) +
  theme_void() +
  labs(title = "COVID-19 in Sweden",
       subtitle = paste("Increase in confirmed cases (%), last 7 days\ndata: c19.se, fetched ", last(c19se$day), sep = ""))

# Save
ggsave("incr_cases.png", width = 6.5, height = 6.5, units = "in", dpi = 300)

# Increase in deaths, last 7 days
set.seed(day(Sys.Date()) + 6)
cities_sample <- sample_n(cities2, 3) %>%
  rbind(bigcities)

ggplot(c19se_incr_map) +
  geom_polygon(aes(x = long, y = lat, group = group, fill = incr_deaths * 100), color = "black") +
  geom_polygon(data = filter(map_tidy, group %in% c(5.2, 19.2, 21.2)),
               aes(x = long, y = lat, group = group), fill = "white", color = "black") +
  geom_point(data = cities_sample, aes(x = long, y = lat), shape = 21, fill = "red", size = 2, stroke = 0.8, alpha = 0.7) +
  geom_label_repel(data = cities_sample, aes(x = long, y = lat, label = city),
                   force = 3, box.padding = unit(0.35, "lines"), size = 3,
                   alpha = 0.6, seed = 1234) +
  geom_label_repel(data = cities_sample, aes(x = long, y = lat, label = city),
                   force = 3, box.padding = unit(0.35, "lines"), size = 3,
                   alpha = 1, fill = NA, seed = 1234) +
  coord_map() +
  scale_fill_viridis("", limits = c(0, NA)) +
  theme_void() +
  labs(title = "COVID-19 in Sweden",
       subtitle = paste("Increase in deaths (%), last 7 days\ndata: c19.se, fetched ", last(c19se$day), sep = ""))

# Save
ggsave("incr_deaths.png", width = 6.5, height = 6.5, units = "in", dpi = 300)

# Increase in confirmed cases, last 7 days, as bar chart
c19se_incr %>%
  ggplot(aes(x = reorder(county, incr_cases))) +
  geom_bar(aes(y = incr_cases * 100, fill = incr_cases * 100),
           stat = "identity") +
  geom_label(aes(y = 0, label = cases_first), size = 3, hjust = 1) +
  geom_label(aes(y = incr_cases * 100, label = cases_last), size = 3, hjust = 1) +
  scale_fill_viridis() +
  coord_flip() +
  theme_minimal() +
  labs(y = "increase / %", x = "", title = "COVID-19 in Sweden",
       subtitle = paste("Increase in confirmed cases, last 7 days (%)\ndata: c19.se, fetched ", last(c19se$day), sep = "")) +
  guides(fill = FALSE) +
  scale_y_continuous(limits = c(-10, with(c19se_incr, max(incr_cases[is.finite(incr_cases)])) * 100 + 20))

# Save
ggsave("incr_cases_bar.png", width = 5.5, height = 7, units = "in", dpi = 300)

# Increase in deaths, last 7 days, as bar chart
c19se_incr %>%
  ggplot(aes(x = reorder(county, incr_deaths))) +
  geom_bar(aes(y = incr_deaths * 100, fill = incr_deaths * 100),
           stat = "identity") +
  geom_label(aes(y = 0, label = death_first), size = 3, hjust = 1) +
  geom_label(aes(y = incr_deaths * 100, label = death_last), size = 3, hjust = 1) +
  scale_fill_viridis() +
  coord_flip() +
  theme_minimal() +
  labs(y = "increase / %", x = "", title = "COVID-19 in Sweden",
       subtitle = paste("Increase in deaths, last 7 days (%)\ndata: c19.se, fetched ", last(c19se$day), sep = "")) +
  guides(fill = FALSE) +
  scale_y_continuous(limits = c(-20, with(c19se_incr, max(incr_deaths[is.finite(incr_deaths)])) * 100 + 20))

# Save
ggsave("incr_deaths_bar.png", width = 5.5, height = 7, units = "in", dpi = 300)

### Line chart of cases/deaths vs day, by region

# Want to show full data set as background. To do this, making a copy but renaming
# county column so that it shows in every facet in the plot.
c19se_blank <- c19se %>%
  ungroup %>%
  rename(county_ = county)

# Create the plot, confirmed cases (log scale) vs day, faceted by region
c19se %>%
  ggplot(aes(x = day, y = cum_cases)) +
  geom_path(data = c19se_blank, aes(group = county_), color = "grey90", size = 0.4) +
  geom_path(aes(color = county), size = 0.8) +
  scale_y_log10() +
  facet_wrap(~ county, nrow = 5) +
  theme_minimal() +
  scale_x_date(date_labels = "%d/%m") +
  guides(color = FALSE) +
  theme(axis.text.x = element_text(angle = -45, hjust = 0)) +
  labs(x = "", y = "confirmed cases",
       title = "COVID-19 in Sweden",
       subtitle = paste("confirmed cases by county, last 30 days\ndata: c19.se, fetched ", last(c19se$day), sep = ""))

# Save
ggsave("cases_by_county.png", width = 6.5, height = 7.5, units = "in", dpi = 300)

# Deaths vs day (log scale), faceted by region
c19se %>%
  ggplot(aes(x = day, y = cum_deaths)) +
  geom_path(data = c19se_blank, aes(group = county_), color = "grey90", size = 0.4) +
  geom_path(aes(color = county), size = 0.8) +
  scale_y_log10() +
  facet_wrap(~ county, nrow = 5) +
  theme_minimal() +
  scale_x_date(date_labels = "%d/%m") +
  guides(color = FALSE) +
  theme(axis.text.x = element_text(angle = -45)) +
  labs(x = "", y = "deaths",
       title = "COVID-19 in Sweden",
       subtitle = paste("deaths by region, last 30 days\ndata: c19.se, fetched ", last(c19se$day), sep = ""))

# Save
ggsave("deaths_by_county.png", width = 6.5, height = 7.5, units = "in", dpi = 300)

# Rolling 7-day change in cases/deaths by county
roll_incr <- lapply(split(c19se, c19se$county), function(df) {

  df$incr_cases <- c(rep(NA, 7),
                     sapply(8:nrow(df), function(i) {
                       100 * (df$cum_cases[i] - df$cum_cases[i-7]) / df$cum_cases[i-7]
                     })
  )

  df$incr_deaths <- c(rep(NA, 7),
                      sapply(8:nrow(df), function(i) {
                        100 * (df$cum_deaths[i] - df$cum_deaths[i-7]) / df$cum_deaths[i-7]
                      })
  )

  return(df)

}) %>% do.call(rbind, .)

roll_incr_blank <- roll_incr %>%
  ungroup %>%
  rename(county_ = county)

roll_incr %>%
  ggplot(aes(x = day, y = incr_cases)) +
  geom_path(data = roll_incr_blank, aes(group = county_), color = "grey90", size = 0.4) +
  geom_path(aes(color = county), size = 0.8) +
  coord_cartesian(ylim = c(0, 300)) +
  facet_wrap(~ county, nrow = 5) +
  theme_minimal() +
  scale_x_date(date_labels = "%d/%m") +
  guides(color = FALSE) +
  theme(axis.text.x = element_text(angle = -45, hjust = 0)) +
  labs(x = "", y = "change in confirmed cases, prev. 7 days / %",
       title = "COVID-19 in Sweden",
       subtitle = paste("rolling 7-day change in confirmed cases\ndata: c19.se, fetched ", last(c19se$day), sep = ""))

ggsave("rollincr_cases.png", width = 6.5, height = 7.5, units = "in", dpi = 300)

roll_incr %>%
  ggplot(aes(x = day, y = incr_deaths)) +
  geom_path(data = roll_incr_blank, aes(group = county_), color = "grey90", size = 0.4) +
  geom_path(aes(color = county), size = 0.8) +
  facet_wrap(~ county, nrow = 5) +
  theme_minimal() +
  scale_x_date(date_labels = "%d/%m") +
  guides(color = FALSE) +
  theme(axis.text.x = element_text(angle = -45, hjust = 0)) +
  labs(x = "", y = "change in deaths, prev. 7 days / %",
       title = "COVID-19 in Sweden",
       subtitle = paste("rolling 7-day change in deaths\ndata: c19.se, fetched ", last(c19se$day), sep = ""))

ggsave("rollincr_deaths.png", width = 6.5, height = 7.5, units = "in", dpi = 300)

## Summary data for the whole country.
summary <- c19se %>%
  group_by(day) %>%
  summarise(sum_cases = sum(cases), sum_deaths = sum(deaths),
            cumsum_cases = sum(cum_cases), cumsum_deaths = sum(cum_deaths))

# Line chart, summary of cases/deaths vs time, for whole country
summary %>%
  select(day, cumsum_cases, cumsum_deaths) %>%
  gather(key = "key", value = "value", -day) %>%
  ggplot(aes(x = day, y = value, color = key)) +
  geom_path(size = 1) +
  scale_y_log10() +
  scale_color_discrete(labels = c("cases", "deaths")) +
  theme_minimal() +
  labs(x = "", y = "",
       title = paste("COVID-19 in Sweden:", last(summary$cumsum_cases), "cases,",
                     last(summary$cumsum_deaths), "deaths"),
       subtitle = paste("Confirmed cases and deaths, last 30 days\ndata: c19.se, fetched ", last(c19se$day), sep = ""))

# Save  
ggsave("summary.png", width = 5, height = 4, units = "in", dpi = 300)

# Calculate rolling 7-day increase in cases and deaths
summary$incr_cases <- c(rep(NA, 7),
                         sapply(8:nrow(summary), function(i) {
                           100 * (summary$cumsum_cases[i] - summary$cumsum_cases[i-7]) / summary$cumsum_cases[i-7]
                         })
)

summary$incr_deaths <- c(rep(NA, 7),
                          sapply(8:nrow(summary), function(i) {
                            100 * (summary$cumsum_deaths[i] - summary$cumsum_deaths[i-7]) / summary$cumsum_deaths[i-7]
                          })
)

# Plot rolling 7-day change for whole country
summary %>%
  select(day, incr_cases, incr_deaths) %>%
  gather(key = "key", value = "value", -day) %>%
  ggplot(aes(x = day, y = value, color = key)) +
  geom_path(size = 1) +
  coord_cartesian(ylim = c(0, 250)) +
  scale_color_discrete(labels = c("cases", "deaths")) +
  theme_minimal() +
  labs(x = "", y = "change, prev. 7 days / %",
       title = "COVID-19 in Sweden",
       subtitle = paste("Rolling 7-day change in cases and deaths\ndata: c19.se, fetched ", last(c19se$day), sep = ""))

ggsave("summary_rollincr.png", width = 5, height = 4, units = "in", dpi = 300)
comments powered by Disqus