ADVERTENCIA

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.

Fuente

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"

Wrangling

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

Evolución en el tiempo

Infectados, recuperados y fallecidos

# 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()

Comparación de casos confirmados en la misma escala (exponencial)

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()

Mapas

Infecciones confirmadas en el mundo según información más reciente:

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()