Deaths data from Eurostat (demo_r_mwk_ts
):
## Warning in eurotime2date(x, last = FALSE): Unknown time code, W. No date conversion was made.
##
## Please fill bug report at https://github.com/rOpenGov/eurostat/issues.
We remove all countries which failed to provide full report in 2015–2019 (actully it is one such country, Ireland):
## summarise (nn=n()) returns number of weeks
## we assume at least one country provides complete report;
## so max(nn) is the number of weeks from 2015--2019
non.full.reporting <- z %>% filter ( year >= 2015 & year < 2020) %>%
group_by(geo) %>%
summarise (nn = n()) %>%
mutate(mx = max(nn)) %>%
filter (nn != mx)
Just to be sure:
as.data.frame(non.full.reporting)
## geo nn mx
## 1 IE 12 261
Remove them:
incompleted.countries <- as.vector(non.full.reporting$geo)
z <- z %>% filter (! geo %in% incompleted.countries)
We define (weekly) excess mortality as a difference between number of deaths in 2020–2021 (z1
) and 5 year average (2015–2019) for corresponding weeks (z0
). The absolute excess mortality (exm
) is defined as z1 - z0
and the relative excess mortality (exp
) is (z1 - z0)/z0 · 100%
:
## mean weekly deaths 2015--2019
z0 <- z %>% filter ( year >= 2015 & year < 2020) %>%
group_by(geo, week) %>%
summarise (d0 = mean(value, na.rm=T))
## weekly deaths 2020--2021
z1 <- z %>% filter ( year > 2019 ) %>%
group_by(geo, year, week) %>%
summarise ( d1 = sum(value))
## join z0 z1 and compute differences
zz <- left_join(z0, z1, by=c("week", "geo")) %>%
drop_na(d0,d1) %>%
mutate (exp = (d1 - d0)/d0 * 100, exm = d1 - d0 )
zz <- left_join(zz, nn, by=c('geo'='id'))
Compute last week each country reported:
## if NA then the country stop reporting in 2020
zz.last.week <- zz %>% filter (year == 2021) %>%
group_by (geo) %>%
summarise (lw = last(week)) %>%
drop_na(lw)
latestweek <- max (zz.last.week$lw)
The latest data is from 49 week, the oldest data is from 12 week. Countries which did not report in 2021 (UK for example, were removed)
We summarise all weeks (exm
) for each country. Countries which reported last earlier than for 43 week are excluded.
There are 29 countries which reported last for week 43 or later.
Total excess mortality 2020–2021
Per 1 mln population
Percent of `normal’ deaths:
The same as above with Poland highlighted
Faceted line plots
Poland and the rest of Europe:
Polar coordinates (I like Nightingale rose chart)
We use Covide19 deaths/cases from OWiD project (https://github.com/owid/covid-19-data/tree/master/public/data) From the dataset we select country iso code and name (location
) and population, daye, number of cases and deaths. Then compute year, week number in a year (using date2ISOweek
/do not use as.Date
conversion). Next compute summaries for weeks and finally compute per 1mln ratios for cases and deaths.
fileC <- "../../COVID/OWiD/owid-covid-data.csv"
mil <- 1000000
c19d <- read.csv(fileC, sep = ',', header=T, na.string="NA" ) %>%
filter (continent == 'Europe') %>%
select (iso_code,
location, date,
new_cases, new_deaths,
pop=population
) %>%
mutate (yyyy = as.numeric(substr(date, 1, 4)),
ww = as.numeric( substr(date2ISOweek(date), 7,8))
) %>%
group_by(iso_code, yyyy, ww) %>%
summarise(
pop = last(pop),
nd = sum(new_deaths, na.rm=T),
nc = sum(new_cases, na.rm=T),
) %>%
## zamień na 1mln
mutate (
## rok-tydzień-dzieńtygodnia
date = ISOweek2date(sprintf("%i-W%02i-1", yyyy, ww)),
date_string = sprintf("%i-%02i-1",yyyy, ww),
nd1m = nd / pop * mil,
nc1m = nc / pop * mil
)
Dynamics of excess deaths vs COVID deaths
Difference between excess deaths and COVID deaths
Total difference between excess deaths and COVID deaths
Excess deaths as percent of COVID related deaths
Scatter-plot for excess deaths vs covid deaths (red line is a diagonal)
Deaths data from Eurostat (demo_r_mwk_10_ts
; Deaths by week, sex and 10-year age group; https://ec.europa.eu/eurostat/databrowser/view/demo_r_mwk_10/default/table?lang=en):
## Warning in eurotime2date(x, last = FALSE): Unknown time code, W. No date conversion was made.
##
## Please fill bug report at https://github.com/rOpenGov/eurostat/issues.
## [1] "TOTAL" "UNK" "Y_GE80" "Y_GE90" "Y_LT10" "Y10-19" "Y20-29" "Y30-39"
## [9] "Y40-49" "Y50-59" "Y60-69" "Y70-79" "Y80-89"
The age
groups: TOTAL, UNK, Y_GE80, Y_GE90, Y_LT10, Y10-19, Y20-29, Y30-39, Y40-49, Y50-59, Y60-69, Y70-79, Y80-89. We skip all sex
levels (F, M, T) except T
(ie total). We combine Y_LT10
–Y50-59
into one group (00-59
) and recode the names of the remaining groups. Group Y_GE80
is redundant so we skip it:
There are r
levels(z$age)` age groups now.
Check how big is UNK
(unknown) group:
There are r
total.unknown` unclassified deaths. We can safely skip this age group.
We compare total deaths and sum of the deaths from other age categories. There should be no difference if the data is consistent:
Some countries have problems:
geo | td | mfd | diff |
---|---|---|---|
AL | 146985 | 146929 | 56 |
DK | 802986 | 802984 | 2 |
EE | 363776 | 363101 | 675 |
EL | 858096 | 858046 | 50 |
ES | 8671762 | 8671418 | 344 |
FR | 5405483 | 5392285 | 13198 |
HR | 1137121 | 1136946 | 175 |
HU | 2891654 | 2891421 | 233 |
LV | 665998 | 665898 | 100 |
PT | 2363331 | 2363050 | 281 |
RS | 2249907 | 2248710 | 1197 |
UK | 3693775 | 3693483 | 292 |
French is strench (as usual):
year | total | 90-and-more | 00-59 | 60-69 | 70-79 | 80-89 |
---|---|---|---|---|---|---|
2013 | 567712 | 136887 | 71014 | 69627 | 94020 | 196163 |
2014 | 557102 | 137442 | 68552 | 70308 | 90667 | 190133 |
2015 | 604310 | 160424 | 70529 | 75123 | 95559 | 202674 |
2016 | 590836 | 160662 | 66894 | 73957 | 94733 | 194590 |
2017 | 604105 | 171141 | 65825 | 73933 | 97866 | 195340 |
2018 | 607786 | 175503 | 65481 | 73432 | 100728 | 192642 |
2019 | 611297 | 178731 | 63662 | 72160 | 103186 | 189473 |
2020 | 678679 | 203626 | 65065 | 76458 | 119094 | 209300 |
2021 | 583656 | 172219 | 57116 | 67969 | 109192 | 173185 |
There are no data for age groups for France in 2020. So age-group analysis for this country is not possible.
Poland and the rest of Europe: