CORONAVIRUS: Análisis de datos con R - TUTORIAL

En las últimas semanas el brote de coronavirus (2019-nCoV) ha hecho noticia alrededor del mundo. Es momento de cuidarnos pero NO de quedarnos quietos, por eso podemos aprovechar esta oportunidad para seguir aprendiendo.

El desafío propuesto en #datosdemieRcoles consiste en analizar los datos disponibles sobre casos reportados, muertes y personas que se han recuperado. Por mi parte, les comparto el código que utilicé para crear un ranking de países, un mapa interactivo y un gráfico animado que muestra la evolución a través del tiempo de los casos confirmados en Argentina y sus países limítrofes.

Los datos fueron obtenidos desde el repositorio oficial del Centro para Ciencia de Sistemas e Ingeniería (CCSE) de la Universidad John Hopkins. Estos set de datos se actualizan diariamente.

¿Qué es #datosdemiercoles?

Datos de miércoles es el primo latinoamericano de #tidytuesday, un proyecto semanal de datos organizado por la comunidad de R, que busca que sus participantes desarrollen sus habilidades procesando datos para crear gráficos significativos usando ggplot2, tidyr, dplyr y otras herramientas del tidyverse.

El objetivo de #datosdemiercoles es aplicar tus habilidades en un desafío concreto, recibir retroalimentación, explorar el trabajo de otras personas y conectarte con la comunidad hispanohablante de R. Se trata de generar un espacio de diálogo seguro y amable para practicar tus habilidades procesando y visualizando datos, independiente de tu nivel de manejo de R.

En primer lugar descargo los datos y pongo la base en condiciones para poder realizar el análisis.

confirmados <- readr::read_csv("https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_19-covid-Confirmed.csv")
muertes <- readr::read_csv("https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_19-covid-Deaths.csv")
recuperados <- readr::read_csv("https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_19-covid-Recovered.csv")

#Transformamos el dataset de confirmaciones 
df_confirmaciones <- reshape2::melt(confirmados, id.vars = colnames(confirmados)[1:4])
df_confirmaciones$Fechas <- as.Date(df_confirmaciones$variable,  format = "%m/%e/%y")
#Creo una variable para unir los 3 datasets
df_confirmaciones$campo_unir<- as.factor(paste(df_confirmaciones$Lat, df_confirmaciones$Long, df_confirmaciones$Fechas, sep="_"))
colnames(df_confirmaciones)[6]<- "infectados"

df_muertes <- reshape2::melt(muertes, id.vars = colnames(muertes)[1:4])
df_muertes$Fechas <- as.Date(df_muertes$variable,  format = "%m/%e/%y")
df_muertes$campo_unir<- as.factor(paste(df_muertes$Lat, df_confirmaciones$Long, df_muertes$Fechas, sep="_"))
colnames(df_muertes)[6]<-"muertes"

df_recuperados <- reshape2::melt(recuperados, id.vars = colnames(recuperados)[1:4])
df_recuperados$Fechas <- as.Date(df_recuperados$variable,  format = "%m/%e/%y")
df_recuperados$campo_unir<- as.factor(paste(df_recuperados$Lat, df_recuperados$Long, df_recuperados$Fechas, sep="_"))
colnames(df_recuperados)[6]<-"recuperados"

#Unos los datasets
df<- df_confirmaciones[,-5]
df$muertes<- df_muertes$muertes[match(df$campo_unir, df_muertes$campo_unir)]
df$recuperados<- df_recuperados$recuperados[match(df$campo_unir, df_recuperados$campo_unir)]

#Dado que la suma entre pacientes muertos y pacientes recuperados no es igual a la cantidad de pacientes 
#confirmados, creo la variable "Enfermos" para cuantificar los pacientes confirmados que aun siguen enfermos.
df$enfermos<- df$infectados-df$muertes-df$recuperados
rm(confirmados, muertes, recuperados, df_confirmaciones, df_muertes, df_recuperados)
colnames(df)[2]<- "COUNTRY"

El siguiente paso consiste en identificar cuáles son las preguntas para las cuales quisiera encontrar una respuesta en los datos.

Ranking de países según personas infectadas

#Filtro la base quedándome con la info de la fecha mas actual.
df_obj1<- subset(df, df$Fechas=="2020-03-19")
#Hago una agregacion de las variables por país, porque hay paises para los que tengo la información repartida por pcia.
df_obj1<- aggregate(df_obj1[,c(5,8,9,10)], by= list(df_obj1$COUNTRY), FUN= function(x) c(sum(x)))  
colnames(df_obj1)[1]<-"COUNTRY"
df_obj1$COUNTRY<-as.factor(df_obj1$COUNTRY)
df_obj1<- df_obj1[order(df_obj1$infectados, decreasing = TRUE),]

library(formattable)
library(data.table)
library(DT)

rownames(df_obj1)<-NULL
as.datatable(
  formattable(df_obj1, rownames=FALSE ,list(
  infectados = formatter("span",
                                  style = x ~ style(color = "orange"),
                                  x ~ sprintf("%g (rank: %02g)", x, rank(-x))),
   muertes = formatter("span",
                         style = x ~ style(color = "red"),
                         x ~ sprintf("%g (rank: %02g)", x, rank(-x))),
   recuperados = formatter("span",style = x ~ style(color = "green")),
   enfermos = formatter("span",style = x ~ style(color = "orange"))
)))

Los datos fueron obtenidos desde el repositorio oficial del Centro para Ciencia de Sistemas e Ingeniería (CCSE) de la Universidad John Hopkins. La información está presentada a la fecha ‘19-03-20’

El coronavirus se ha extendido más de 150 países y afecta a más de 245.000 personas, de las que 10.000 han perdido la vida.

A continuación se presenta un mapa de calor en el cual se puede identificar a los países en una escala de rojos según la cantidad de personas infectadas. Dado que la base de datos cuenta con información por provincia y región sólo para algunos países, al deslizar el mouse se obtiene información a nivel país y al hacer click sobre los íconos amarillos y azules se puede obtener la información desagregada a nivel provincia/región.

library(rgdal)
library(leaflet)

#shapefilemundial
df_mapa<- readOGR("C:/Users/elfer/OneDrive/Desktop/Codigos_R/Mapas/Capa mundial/capa_mundial_ok.shp")
## OGR data source with driver: ESRI Shapefile 
## Source: "C:\Users\elfer\OneDrive\Desktop\Codigos_R\Mapas\Capa mundial\capa_mundial_ok.shp", layer: "capa_mundial_ok"
## with 256 features
## It has 5 fields
#head(df_mapa@data)

df_obj1$Color<- ifelse(df_obj1$infectados<=50, 1,
                                     ifelse(df_obj1$infectados<=100, 2,
                                     ifelse(df_obj1$infectados<=300, 3,
                                     ifelse(df_obj1$infectados<=500,4,
                                     ifelse(df_obj1$infectados<=750, 5,
                                     ifelse(df_obj1$infectados<=1000,6,
                                     ifelse(df_obj1$infectados<=1500,7,
                                     ifelse(df_obj1$infectados<=2000,8,
                                     ifelse(df_obj1$infectados<=2500,9,
                                     ifelse(df_obj1$infectados<=3000,10,
                                     ifelse(df_obj1$infectados<=5000,11,
                                     ifelse(df_obj1$infectados<=10000,12,
                                     ifelse(df_obj1$infectados<=20000,13,
                                     ifelse(df_obj1$infectados<=30000,14,
                                     ifelse(df_obj1$infectados<=50000,15,16
                                    )))))))))))))))

df_obj2 <- merge(df_mapa,df_obj1, by="COUNTRY")
df_obj2<- subset(df_obj2, COUNTRY%in%df_obj1$COUNTRY)

df_obj2_pcias<- subset(df, df$Fechas=="2020-03-19" & df$infectados>0)

library(RColorBrewer)
pal <- colorNumeric(
  palette=c( "#FDD0A2","#FDAE6B","#FD8D3C", "#FD8D3C" ,"#F16913" ,"#F46D43", "#D73027",  "#A50026"),
  domain = df_obj2@data$Color)

#Los colores los pongo en funcion al nro de casos por pais
#Pero tmb uso un segundo dataset para aprovechar la info por pcia en los casos en los que tenga la info
  
g<-leaflet(data = df_obj2) %>%
    addTiles()%>%
    addPolygons(
      weight = 1,
      fillOpacity = 0.8, 
      color = "black", 
      fillColor = ~pal(df_obj2@data$Color),
      # popup = paste(df_mapa@data$PAIS, variable, sep=" "), #%>% #etiqueta los paises
      label=paste(df_obj2@data$COUNTRY,
                  
                  "Infectados:", df_obj2@data$infectados, 
                  "Muertes:", df_obj2@data$muertes,
                  "Recuperados:", df_obj2@data$recuperados, sep=" "))%>%
  
  addMarkers(lng=~df_obj2_pcias$Long, lat=~df_obj2_pcias$Lat, 
             label=~paste("Info", df_obj2_pcias$COUNTRY, sep=" "),
             popup = paste("Pcia/Estado:",df_obj2_pcias$`Province/State`, 
                           
                           "Infectados:", df_obj2_pcias$infectados, 
                           
                           "Muertes:", df_obj2_pcias$muertes,
                           
                           "Recuperados:", df_obj2_pcias$recuperados, sep=" "),
             clusterOptions = markerClusterOptions(removeOutsideVisibleBounds = F),
             labelOptions = labelOptions(noHide = F,
                                         direction = 'auto'))
     

g

Los datos fueron obtenidos desde el repositorio oficial del Centro para Ciencia de Sistemas e Ingeniería (CCSE) de la Universidad John Hopkins. La información está presentada a la fecha ‘19-03-20’

Por último, voy a acotar el análisis para los países “Argentina”, “Brazil”, “Bolivia”, “Chile”, “Uruguay” y “Paraguay”. Dentro de este grupo, el primer caso tuvo lugar el “2020-02-27”. Por ende, voy a analizar la evolución a través del tiempo de los casos confirmados en Argentina y sus países limítrofes, a partir de dicha fecha.

###Objetivo 3
library(gganimate)
library(gifski)

df_obj3<- subset(df, df$COUNTRY %in% c("Argentina",  "Brazil", "Bolivia" ,  "Chile" , "Uruguay","Paraguay") & df$Fechas>"2020-02-27")

ggplot(df_obj3,aes(x = Fechas, 
                y = infectados , 
                color =COUNTRY
)) + 
  geom_line(size=1.5) + 
  scale_x_date(breaks = scales::pretty_breaks(n=11)) +
  labs(x = "Fecha", y = "Personas infectadas", title = "Evolución a través del tiempo de los casos
confirmados en Argentina y sus países limítrofes") +
  theme_minimal()+
  theme(plot.title = element_text(hjust = 0.5),
        plot.background = element_rect(size = 1, color = "white", fill ="#C6DBEF"),
        text=element_text(size = 15, family = "Serif", color =  "black"),
        axis.text.y = element_text(colour = "black"),
        axis.text.x = element_text(colour ="black"),
        axis.text=element_text(size = 8),
        legend.position = "top",
        legend.justification = c("center", "top"),
        legend.box.just = "center",
        legend.title = element_blank()
        ) +
  transition_reveal(Fechas)
Los datos fueron obtenidos desde el repositorio oficial del Centro para Ciencia de Sistemas e Ingeniería (CCSE) de la Universidad John Hopkins. La información está presentada a la fecha ‘19-03-20’

Los datos fueron obtenidos desde el repositorio oficial del Centro para Ciencia de Sistemas e Ingeniería (CCSE) de la Universidad John Hopkins. La información está presentada a la fecha ‘19-03-20’

anim_save("corona_ok.gif")