Ante una crisis global cuyas causas aún no se comprenden del todo, y cuya dinámica cambia cada día, se desaconseja extraer conclusiones de los datos disponibles.
Sin la intervención de expertxs, ni un cuidadoso análisis en contexto, toda información producida al procesar estos datos debe ser considerada un simple ejercicio exploratorio.
Usaremos el repositorio de datos mantenido por el Center for Systems Science and Engineering de la Universidad Johns Hopkins. Ofrece conteos actualizados día a día de infecciones confirmadas, muertes y recuperaciones por país (y subregión, donde se encuentre disponible).
Adquirimos los datos:
confirmados <- read.csv("https://github.com/CSSEGISandData/COVID-19/raw/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv")
recuperados <- read.csv("https://github.com/CSSEGISandData/COVID-19/raw/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_recovered_global.csv")
muertos <- read.csv("https://github.com/CSSEGISandData/COVID-19/raw/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_deaths_global.csv")
En los datos tenemos
names(confirmados)
## [1] "Province.State" "Country.Region" "Lat" "Long"
## [5] "X1.22.20" "X1.23.20" "X1.24.20" "X1.25.20"
## [9] "X1.26.20" "X1.27.20" "X1.28.20" "X1.29.20"
## [13] "X1.30.20" "X1.31.20" "X2.1.20" "X2.2.20"
## [17] "X2.3.20" "X2.4.20" "X2.5.20" "X2.6.20"
## [21] "X2.7.20" "X2.8.20" "X2.9.20" "X2.10.20"
## [25] "X2.11.20" "X2.12.20" "X2.13.20" "X2.14.20"
## [29] "X2.15.20" "X2.16.20" "X2.17.20" "X2.18.20"
## [33] "X2.19.20" "X2.20.20" "X2.21.20" "X2.22.20"
## [37] "X2.23.20" "X2.24.20" "X2.25.20" "X2.26.20"
## [41] "X2.27.20" "X2.28.20" "X2.29.20" "X3.1.20"
## [45] "X3.2.20" "X3.3.20" "X3.4.20" "X3.5.20"
## [49] "X3.6.20" "X3.7.20" "X3.8.20" "X3.9.20"
## [53] "X3.10.20" "X3.11.20" "X3.12.20" "X3.13.20"
## [57] "X3.14.20" "X3.15.20" "X3.16.20" "X3.17.20"
## [61] "X3.18.20" "X3.19.20" "X3.20.20" "X3.21.20"
## [65] "X3.22.20" "X3.23.20" "X3.24.20" "X3.25.20"
## [69] "X3.26.20" "X3.27.20" "X3.28.20" "X3.29.20"
## [73] "X3.30.20"
Pasaremos los datos de formato serie de tiempo (con cada fila conteniendo observaciones de todos los días) a formato “tidy” (en cada fila una observación). También combinaremos los tres datasets en una sola tabla. Esto facilitará el análisis posterior, al permitir filtrar los datos con facilidad por fecha y categoría de incidente.
Vamos a usar los paquetes tidyverse por sus funciones de transformación de datos, y lubridate para manejar fechas.
library(tidyverse)
library(lubridate)
La receta:
covid19 <- mutate(confirmados, Category = "Confirmed") %>%
bind_rows(mutate(recuperados, Category = "Recovered")) %>%
bind_rows(mutate(muertos, Category = "Deaths")) %>%
select(Province.State:Long, Category, everything()) %>%
pivot_longer(-(Province.State:Category), names_to = "Date", values_to = "Value") %>%
mutate(Date = mdy(str_remove(Date, "X")))
Al menos una vez ocurrió que los datos de origen traían la columna de la fecha más reciente con valores faltantes (NA’s) que luego fueron reemplazados por los conteos del día. Con esto evitamos que eso traiga problema, retirando los valores faltantes.
covid19 <- covid19 %>%
filter(!is.na(Value))
Así, podemos repetir el procedimiento de descarga y procesamiento de datos con frecuencia, sin necesidad de cambiar nada en el código.
Luego, para obtener una fecha en particular:
covid19 %>%
filter(Date == ymd("2020 03 01")) %>%
head
## # A tibble: 6 x 7
## Province.State Country.Region Lat Long Category Date Value
## <chr> <fct> <dbl> <dbl> <chr> <date> <int>
## 1 "" Afghanistan 33 65 Confirmed 2020-03-01 1
## 2 "" Albania 41.2 20.2 Confirmed 2020-03-01 0
## 3 "" Algeria 28.0 1.66 Confirmed 2020-03-01 1
## 4 "" Andorra 42.5 1.52 Confirmed 2020-03-01 0
## 5 "" Angola -11.2 17.9 Confirmed 2020-03-01 0
## 6 "" Antigua and Barbuda 17.1 -61.8 Confirmed 2020-03-01 0
O para la última fecha disponible:
covid19 %>%
filter(Date == max(Date)) %>%
head
## # A tibble: 6 x 7
## Province.State Country.Region Lat Long Category Date Value
## <chr> <fct> <dbl> <dbl> <chr> <date> <int>
## 1 "" Afghanistan 33 65 Confirmed 2020-03-30 170
## 2 "" Albania 41.2 20.2 Confirmed 2020-03-30 223
## 3 "" Algeria 28.0 1.66 Confirmed 2020-03-30 584
## 4 "" Andorra 42.5 1.52 Confirmed 2020-03-30 370
## 5 "" Angola -11.2 17.9 Confirmed 2020-03-30 7
## 6 "" Antigua and Barbuda 17.1 -61.8 Confirmed 2020-03-30 7
# evitamos notación científica en los gráficos
options(scipen = 20)
paises_a_comparar <- c("Argentina", "Brazil", "China", "Italy", "Korea, South")
covid19 %>%
filter(Country.Region %in% paises_a_comparar) %>%
group_by(Category, Date, Country.Region) %>%
summarise(Value = sum(Value)) %>%
ggplot() +
geom_col(aes(x = Date, y = Value, fill = Category)) +
facet_wrap(~Country.Region, scales = "free") +
scale_fill_brewer(palette = "Set2") +
labs(title = "COVID19: cantidad de casos",
fill = "Situación",
caption = "fuente: 2019 Novel Coronavirus COVID-19 Data Repository by Johns Hopkins CSSE",
y = NULL, x = NULL) +
theme_minimal()
covid19 %>%
filter(Country.Region %in% paises_a_comparar, Category == "Confirmed") %>%
group_by(Date, Country.Region) %>%
summarise(Value = sum(Value)) %>%
ggplot() +
geom_path(aes(x = Date, y = Value, color = Country.Region)) +
scale_y_log10() +
labs(title = "COVID19: Infecciones confirmadas",
color = "",
x = NULL, y = NULL,
caption = "fuente: 2019 Novel Coronavirus COVID-19 Data Repository by Johns Hopkins CSSE") +
theme_minimal()
ggplot() +
geom_polygon(data = map_data("world"),
aes(x = long, y = lat, group = group),
fill="gray90", colour = "white") +
# Retiramos los lugares donde el conteo aún es 0
geom_point(data = filter(covid19, Date == max(Date), Category == "Confirmed", Value > 0),
aes(x = Long, y = Lat, size = Value),
alpha = .5, color = "orange") +
# Usamos escala logarítmica
scale_size(trans = "log10") +
labs(title = "COVID19: Infecciones confirmadas",
subtitle = paste("al", max(covid19$Date)),
caption = "fuente: 2019 Novel Coronavirus COVID-19 Data Repository by Johns Hopkins CSSE") +
theme_minimal()