2020 excess mortality & voting patterns in CH
Redistributed cantonal deaths
Data
Canton
Expected deaths by age X sex X canton in 2020 from Riou et al..
Contains iterations of diff results
max(exp_deaths_2020_kt$it)
[1] 1000
Example of one iteration
Name | Piped data |
Number of rows | 260 |
Number of columns | 6 |
_______________________ | |
Column type frequency: | |
character | 3 |
numeric | 3 |
________________________ | |
Group variables | None |
Variable type: character
skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
---|---|---|---|---|---|---|---|
canton | 0 | 1 | 2 | 2 | 0 | 26 | 0 |
age_group | 0 | 1 | 3 | 5 | 0 | 5 | 0 |
sex | 0 | 1 | 4 | 6 | 0 | 2 | 0 |
Variable type: numeric
skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
---|---|---|---|---|---|---|---|---|---|---|
it | 0 | 1 | 1.00 | 0.00 | 1 | 1.00 | 1.0 | 1.00 | 1 | ▁▁▇▁▁ |
exp_deaths | 0 | 1 | 216.61 | 399.69 | 0 | 22.75 | 75.5 | 217.25 | 2857 | ▇▁▁▁▁ |
observed2 | 0 | 1 | 254.35 | 491.21 | 0 | 23.00 | 81.0 | 247.75 | 3891 | ▇▁▁▁▁ |
Municipality
Data prepared in 02.Rmd
. Collapsing age groups and
renaming variables to match cantonal estimates.
= read_rds("data/BfS-closed/monthly_deaths/w_deaths_2015_2020_year_fin.Rds") %>%
w_deaths_2020_year_fin filter(year == 2020) %>% select(-year) %>%
rename(age_group = age,
canton = KTNAME) %>%
mutate(age_group = if_else(age_group == "40-49", "40-59", age_group),
age_group = if_else(age_group == "50-59", "40-59", age_group)) %>%
group_by(canton, GMDNR, age_group, sex) %>%
summarise(observed = sum(observed),
pop_mid_poi = sum(pop_mid_poi)) %>%
ungroup()
Name | Piped data |
Number of rows | 21450 |
Number of columns | 6 |
_______________________ | |
Column type frequency: | |
character | 3 |
numeric | 3 |
________________________ | |
Group variables | None |
Variable type: character
skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
---|---|---|---|---|---|---|---|
canton | 0 | 1 | 2 | 2 | 0 | 26 | 0 |
age_group | 0 | 1 | 3 | 5 | 0 | 5 | 0 |
sex | 0 | 1 | 4 | 6 | 0 | 2 | 0 |
Variable type: numeric
skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
---|---|---|---|---|---|---|---|---|---|---|
GMDNR | 0 | 1 | 3289.82 | 2133.49 | 1 | 1067 | 3296 | 5411 | 6810 | ▇▃▅▅▇ |
observed | 0 | 1 | 3.55 | 18.99 | 0 | 0 | 1 | 3 | 1493 | ▇▁▁▁▁ |
pop_mid_poi | 0 | 1 | 403.70 | 1769.38 | 0 | 44 | 123 | 336 | 116058 | ▇▁▁▁▁ |
Spatial
= read_rds("data/BfS/kt.Rds")
kt = read_rds("data/BfS/gg.Rds")
gg = read_rds("data/BfS/tg3o.Rds")
tg3o = read_rds("data/BfS/se_alt.Rds") se_alt
Downscale function
@jriou method to downscale cantonal deaths to municipality level.
source("R/downscale_year.R")
Downscale
= downscale_year(exp_deaths_2020_kt, w_deaths_2020_year_fin) %>%
exp_deaths_2020_year rename(
munici_pop = pop_mid_poi,
munici_observed = observed,
cant_exp_deaths = exp_deaths,
cant_observed = observed2)
Again, result contains iterations of diff results
max(exp_deaths_2020_year$it)
[1] 1000
Example of one iteration
Name | Piped data |
Number of rows | 21450 |
Number of columns | 12 |
_______________________ | |
Column type frequency: | |
character | 3 |
numeric | 9 |
________________________ | |
Group variables | None |
Variable type: character
skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
---|---|---|---|---|---|---|---|
canton | 0 | 1 | 2 | 2 | 0 | 26 | 0 |
age_group | 0 | 1 | 3 | 5 | 0 | 5 | 0 |
sex | 0 | 1 | 4 | 6 | 0 | 2 | 0 |
Variable type: numeric
skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
---|---|---|---|---|---|---|---|---|---|---|
GMDNR | 0 | 1.00 | 3289.82 | 2133.49 | 1 | 1067 | 3296.00 | 5411.00 | 6810 | ▇▃▅▅▇ |
munici_observed | 0 | 1.00 | 3.55 | 18.99 | 0 | 0 | 1.00 | 3.00 | 1493 | ▇▁▁▁▁ |
munici_pop | 0 | 1.00 | 403.70 | 1769.38 | 0 | 44 | 123.00 | 336.00 | 116058 | ▇▁▁▁▁ |
it | 0 | 1.00 | 1.00 | 0.00 | 1 | 1 | 1.00 | 1.00 | 1 | ▁▁▇▁▁ |
cant_exp_deaths | 0 | 1.00 | 404.91 | 589.00 | 0 | 65 | 182.00 | 471.00 | 2857 | ▇▁▁▁▁ |
cant_observed | 0 | 1.00 | 467.83 | 712.77 | 0 | 62 | 173.00 | 547.00 | 3891 | ▇▁▁▁▁ |
p | 9988 | 0.53 | 0.02 | 0.06 | 0 | 0 | 0.01 | 0.02 | 1 | ▇▁▁▁▁ |
munici_exp_deaths | 0 | 1.00 | 2.63 | 13.31 | 0 | 0 | 0.00 | 2.00 | 856 | ▇▁▁▁▁ |
munici_excess | 0 | 1.00 | 0.93 | 6.84 | -17 | 0 | 0.00 | 1.00 | 637 | ▇▁▁▁▁ |
Preps
Aggregates
Iterations collapsed for each municipality strata.
= exp_deaths_2020_year %>%
exp_deaths_2020_year_agg group_by(canton, GMDNR, age_group, sex) %>%
summarise(
# observed
munici_observed = first(munici_observed),
munici_pop = first(munici_pop),
# modelled x1000
# expected
munici_expected_lo = quantile(munici_exp_deaths, 0.025),
munici_expected_med = quantile(munici_exp_deaths, 0.5),
munici_expected_up = quantile(munici_exp_deaths, 0.975),
# excess
munici_excess_lo = quantile(munici_excess, 0.025),
munici_excess_med = quantile(munici_excess, 0.5),
munici_excess_up = quantile(munici_excess, 0.975)
%>%
) ungroup()
Even simpler aggregation to municipality level, ignoring age & sex strata.
= exp_deaths_2020_year_agg %>%
exp_deaths_2020_year_gem group_by(canton, GMDNR) %>%
summarise(
# community level totals
munici_pop = sum(munici_pop),
munici_observed = sum(munici_observed),
munici_expected_med = sum(munici_expected_med),
munici_excess_med = sum(munici_excess_med)
%>%
) ungroup() %>%
# ratio and per pop
mutate(munici_excess_rat = munici_excess_med / munici_expected_med,
munici_excess_pop = (munici_excess_med / munici_pop) * 1000)
Special situation arises in this aggregation when calculating a
ratio of excess deaths to observed deaths. There are
communities where expected number of deaths is zero. That leads to ratio
being Inf
in cases where excess is > 0 and to
NaN
where excess is (also) == 0.
munici_expected_med == 0 <lgl>
# total N=2145 valid N=2145 mean=0.05 sd=0.21
Value | N | Raw % | Valid % | Cum. %
---------------------------------------
FALSE | 2042 | 95.20 | 95.20 | 95.20
TRUE | 103 | 4.80 | 4.80 | 100.00
<NA> | 0 | 0.00 | <NA> | <NA>
These communities’ ratios were recoded to NA
.
Bring covariates
%<>%
exp_deaths_2020_year left_join(read_rds("data/BfS-closed/monthly_deaths/w_deaths_2015_2020_year_fin.Rds") %>%
select(GMDNR, GMDNAME, border,
%>%
median_ssep3_q, r_urban1, r_urban2, r_lang) distinct())
%<>%
exp_deaths_2020_year_agg left_join(read_rds("data/BfS-closed/monthly_deaths/w_deaths_2015_2020_year_fin.Rds") %>%
select(GMDNR, GMDNAME, border,
%>%
median_ssep3_q, r_urban1, r_urban2, r_lang) distinct())
%<>%
exp_deaths_2020_year_gem left_join(read_rds("data/BfS-closed/monthly_deaths/w_deaths_2015_2020_year_fin.Rds") %>%
select(GMDNR, GMDNAME, border,
%>%
median_ssep3_q, r_urban1, r_urban2, r_lang) distinct())
Bring voting
= read_rds("data/voting/covid_jun.Rds") %>%
covid_jun select(GMDNR, jaStimmenInProzent, vote_yes) %>%
rename(vote_yes_jun_perc = jaStimmenInProzent,
vote_yes_jun_cat = vote_yes)
= read_rds("data/voting/covid_nov.Rds") %>%
covid_nov select(GMDNR, jaStimmenInProzent, vote_yes) %>%
rename(vote_yes_nov_perc = jaStimmenInProzent,
vote_yes_nov_cat = vote_yes)
Note: there are few small communities with no voting info - these were excluded.
# A tibble: 4 × 2
canton GMDNAME
<chr> <chr>
1 BE Meienried
2 BE Hellsau
3 BE Deisswil bei Münchenbuchsee
4 BE Niedermuhlern