W tym dokumencie wizualizujemy zawartość rejestru zgonów z Powodu COVID19 w PL udostępnionego przez MZ pod adresem https://basiw.mz.gov.pl/index.html. Porównujemy ten rejestr z danymi z bazy danych nt. pandemii COVID z John Hopkins University.
Baza danych zgonów COVID z John Hopkins University (liczba zgonów dziennie); filter
wyciąga wiersze z danymi dla Polski; select
wyciąga tylko kolumny date
oraz newd
(dzienna liczba zgonów z powodu COVID):
jhu_0 <- read.csv("covid19_JHU.csv", sep = ';', header=T, na.string="NA") %>%
filter ( country == 'Poland') %>%
select (date, newd)
Pierwszy i ostatni dzień
first.jhu.day <- first(jhu_0$date)
last.jhu.day <- last(jhu_0$date)
last.jhu.day
## [1] 2021-12-24
## 724 Levels: 2020-01-01 2020-01-02 2020-01-03 2020-01-04 ... 2021-12-24
Baza BASiW (https://basiw.mz.gov.pl/index.html) zgonów z powodu COVID za rok 2020; Baza zawiera dane indywidualne, ale w bardzo dziwacznym formacie, mianowicie dla każdej kombinacji dnia, województwa, wieku i płci zawiera liczbę zgonów z powodu covid oraz z powodu covid i innych chorób. Ten dziwaczny format zamieniono na dane indywidualne (odpowiednio powielając wiersze). Dodatkowym utrudnieniem jest to, że kolumna wiek zawiera symbol 90+
(który nie jest liczbą)
Z tego drugiego powodu czytam wiek
jako typ znakowy; następnie zamieniamy 95+
arbitralnie na 95
. Następnie zamieniamy typ znakowy na liczbę (as.integer
). Przekodowujemy zmienną zgony_19
(T
zgon z powodu covid19; N
zgon z powodu covid + inne choroby)
basiw2020 <- read.csv("basiw_2020.csv", sep = ';', header=T,
colClasses=c('wojewodztwo' = 'character', 'wiek'='character'),
na.string="NA") %>%
mutate ( wiek = case_when(wiek == '90+' ~ '95', wiek != '90+' ~ wiek )) %>%
select(data, woj=wojewodztwo, zgony_c19, plec, vek=wiek) %>%
mutate (
vek = as.integer(vek),
woj = as.factor(woj),
zgony_c19 = case_when(
zgony_c19 == 0 ~ "N",
zgony_c19 == 1 ~ "T" )) %>%
mutate ( zgony_c19 = as.factor(zgony_c19))
Baza BASiW rok 2021 podobnie jak w roku 2020 zawiera dane pseudo-indywidualne, ale trochę inne; Podobnie jak poprzednio najpierw zamieniane skryptem na dane idywidualne (w sensie jeden wiersz = jeden zgon)
Nie ma nazwy województwa (jak w roku 2020), ale jest nr_teryt. Płeć zawiera dwie wartości K
, M
+ nieznana
.
W związku z tym: teryt_woj
importujemy jako character
(żeby 02
nie zmieniło się w 2
); Płeć też importujemy jako character
, co pozwoli usunąć nienana
i dzięki temu będzie to samo co w bazie w roku 2020.
basiw2021_0 <- read.csv("basiw_2021.csv", sep = ';', header=T,
colClasses=c('teryt_woj' = 'character', 'plec' = 'character',
'wiek'='integer'),
na.string="NA") %>%
mutate ( plec =
case_when(plec == 'nieznana' ~ NA_character_,
plec != 'nieznana' ~ plec )) %>%
select(data=data_rap_zgonu, woj=teryt_woj,
zgony_c19=czy_wspolistniejace, plec, vek=wiek) %>%
mutate (plec = as.factor(plec))
Uwaga na mutate
zmieniające wartości zmiennej płeć. Wszystkie wartości po znaku ~
w poleceniu case_when
muszą być tego samego typu; dlatego wstawiamy NA_character_
a nie (beztypowe) NA
.
Wczytujemy nazwy województw + numery teryt ze stosownego pliku csv:
woj <- read.csv("teryt_wojewodztwa_BB.csv", sep = ';', header=T,
colClasses=c('teryt' = 'character'), na.string="NA")
Łączymy basiw2021
z ramką nazw województw:
basiw2021 <- left_join(basiw2021_0, woj, by=c('woj'='teryt')) %>%
select(data, woj=nazwa, zgony_c19, plec, vek)
Wreszcie wszystkie kolumny w ramkach basiw2021
oraz basiw2020
są tego samego typu; łączymy ramki (w pionie). Nawiasem mówiąc, że należało wykonać aż tyle transformacji żeby otrzymać połączony i ujednolicony plik dla lat 2020 i 2021 jest miarą burdelu i niekompetencji w MZ. Mi by było wstyd publikować dane aż tak na odpierdol, no ale im nie jest:
basiw <- rbind(basiw2020, basiw2021)
## sprawdzamy co wyszło:
first.basiw.day <- first(basiw$data)
last.basiw.day <- last(basiw$data)
last.basiw.day
## [1] 2021-12-28
## 626 Levels: 2020-03-12 2020-03-13 2020-03-14 2020-03-16 ... 2021-12-28
Ustalmy która baza (basiw czy jhu) jest któtsza:
last.day <- last.jhu.day
if (as.Date(last.basiw.day) <= as.Date(last.jhu.day)) {
last.day <- last.basiw.day
}
last.day
## [1] 2021-12-24
## 724 Levels: 2020-01-01 2020-01-02 2020-01-03 2020-01-04 ... 2021-12-24
last.day
to starsza data z dwóch ostatnich;
Sprawdzamy ile mamy:
## zabici łącznie
total.deaths <- nrow(basiw)
Obcinamy bazy baziw i jhu do ostatniego wspólnego dnia' (czyli do dnia
last.day`) a następnie agregujemy wyniki:
## BASIW database ###
## dane dzienne
basiw_d <- basiw %>%
filter (as.Date(data) <= as.Date(last.day) ) %>%
group_by (data) %>%
summarise ( n = n() ) %>%
ungroup()
## dane tygodniowe
basiw_w <- basiw %>%
mutate(
ww = substr(date2ISOweek(data), 1,8)) %>%
group_by (ww) %>%
summarise ( n = n() ) %>%
ungroup() %>%
mutate(dat = ISOweek2date(sprintf("%s-1", ww))) %>%
ungroup()
total.deaths.w <- sum(basiw_w$n)
## JHU database ###
## ta baza już zawiera dane dzienne
jhu <- jhu_0 %>%
filter (as.Date(date) <= as.Date(last.day) )
## dane tygodniowe
jhu_w <- jhu %>%
mutate(
ww = substr(date2ISOweek(date), 1,8)) %>%
group_by (ww) %>%
summarise ( n.jhu = sum(newd) ) %>%
ungroup() %>%
mutate(dat = ISOweek2date(sprintf("%s-1", ww))) %>%
ungroup()
Zgony dziennie baza basiw
p1 <- ggplot(basiw_d, aes(x= as.Date(data, format="%Y-%m-%d"), y=n)) +
geom_smooth(method="loess", se=F, span=spanV) +
geom_line(size=.4, alpha=.5) +
geom_point(size=1, alpha=.5) +
xlab(label="") +
ylab(label="age") +
scale_x_date( labels = date_format("%y/%W"), breaks = mainBreaks) +
theme_nikw()
p1
Zgony tygodniowe baza basiw
p2 <- ggplot(basiw_w, aes(x= as.Date(dat, format="%Y-%m-%d"), y=n)) +
geom_smooth(method="loess", se=F, span=spanV) +
geom_line(size=.4, alpha=.5) +
geom_point(size=1, alpha=.5) +
xlab(label="") +
ylab(label="age") +
scale_x_date( labels = date_format("%y/%W"), breaks = mainBreaks) +
theme_nikw()
p2
Porównanie basiw vs jhu (dane tygodniowe)
basiw_vs_jhu <- left_join(basiw_w, jhu_w, by='dat')
p3 <- basiw_vs_jhu %>%
pivot_longer(cols=c('n', 'n.jhu'), names_to = 'base', values_to = 'v') %>%
ggplot (aes(x= as.Date(dat, format="%Y-%m-%d"), y=v, color=base)) +
##geom_smooth(method="loess", se=F, span=spanV) +
geom_line(size=.4, alpha=.25) +
geom_point(size=1, alpha=.25) +
xlab(label="") +
ylab(label="age") +
scale_x_date( labels = date_format("%y/%W"), breaks = mainBreaks) +
theme_nikw()
p3
## Warning: Removed 1 row(s) containing missing values (geom_path).
## Warning: Removed 1 rows containing missing values (geom_point).
ggsave(plot=p3, file='basiw_vs_jhu.png', width = 9)
## Warning: Removed 1 row(s) containing missing values (geom_path).
## Warning: Removed 1 rows containing missing values (geom_point).
p4 <- basiw_vs_jhu %>%
mutate (d = n - n.jhu) %>%
ggplot (aes(x= as.Date(dat, format="%Y-%m-%d"), y=d)) +
##geom_smooth(method="loess", se=F, span=spanV) +
geom_line(size=.4, alpha=.25) +
geom_point(size=1, alpha=.25) +
xlab(label="") +
ylab(label="age") +
scale_x_date( labels = date_format("%y/%W"), breaks = mainBreaks) +
theme_nikw()
p4
## Warning: Removed 1 row(s) containing missing values (geom_path).
## Warning: Removed 1 rows containing missing values (geom_point).
Generalnie się zgadza, co jest chyba jedynym pozytywem z całego tego ćwiczenia.