library(dplyr)
Para empezar, diseñaremos una pequeña base de datos en la que podemos aplicar distintas técnicas de manipulación.
clase <- c(rep("A", 4), rep("B", 4), rep("C", 4))
tipo <- c(rep("uno", 6), rep("dos", 6))
valor <- c(20,31,24,44,67,70,95,84,52,43,54,61)
data <- data.frame(clase, tipo, valor)
data
## clase tipo valor
## 1 A uno 20
## 2 A uno 31
## 3 A uno 24
## 4 A uno 44
## 5 B uno 67
## 6 B uno 70
## 7 B dos 95
## 8 B dos 84
## 9 C dos 52
## 10 C dos 43
## 11 C dos 54
## 12 C dos 61
Primero utilizaremos la librerÃa dplyr la cual tiene la mayorÃa de las herramientas más utilizadas en la manipulación de dataframes, una de las principales caracterÃsticas de esta librerÃa es el uso un elemento para concatenar ordenes %>% el cual es sumamente útil ya que nos ahorra muchos pasos al momento de la manipulación. Para empezar utilizaremos filter() que permite filtrar los datos según alguna condición o condiciones:
filter(data, clase == "A" & valor > 30)
## clase tipo valor
## 1 A uno 31
## 2 A uno 44
Como se puede ver, podemos filtrar más de una condición agregando &. Otra forma de llegar al mismo resultado es mediante la siguiente sintaxis:
data %>% filter(clase == "A" & valor > 30)
## clase tipo valor
## 1 A uno 31
## 2 A uno 44
Esta es la sintaxis que utilizaremos en lo subsecuente ya que es más útil porque permite concatenar ordenes después de aplicar transformaciones, selecciones o filtrados. PodrÃamos ahora solo querer seleccionar algunas variables del dataframe, para esto utilizamos select():
data %>% select(clase, valor)
## clase valor
## 1 A 20
## 2 A 31
## 3 A 24
## 4 A 44
## 5 B 67
## 6 B 70
## 7 B 95
## 8 B 84
## 9 C 52
## 10 C 43
## 11 C 54
## 12 C 61
PodrÃamos ahora concatenar esta orden con un filtrado, por ejemplo, solo para valores mayores a 50:
data %>% select(clase, valor) %>% filter(valor > 50)
## clase valor
## 1 B 67
## 2 B 70
## 3 B 95
## 4 B 84
## 5 C 52
## 6 C 54
## 7 C 61
Si nos interesa un filtrado, no sobre caracterÃsticas sino sobre un grupo de filas utilizaremos slice():
data %>% slice(2:5)
## clase tipo valor
## 1 A uno 31
## 2 A uno 24
## 3 A uno 44
## 4 B uno 67
Podemos obtener muestras aleatorias de los datos con la función sample_n():
data %>%sample_n(5, replace = FALSE)
## clase tipo valor
## 1 A uno 44
## 2 C dos 61
## 3 C dos 52
## 4 A uno 31
## 5 A uno 24
En ocasiones nos interesa modificar la base de tal manera que no tengamos los valores originales, sino sumas, medias o alguna operación respecto a un factor en particular. Para nuestro ejemplo podrÃa estar interesado en saber el promedio de cada valor por clase. Esto se logra con group_by() que nos dice cual es el factor a agrupar y summarise() que nos permite crear una variable nueva resultado de aplicar la función al grupo.
data %>% group_by(clase) %>% summarise(media = mean(valor))
## # A tibble: 3 x 2
## clase media
## <fct> <dbl>
## 1 A 29.8
## 2 B 79
## 3 C 52.5
Para ordenar la base de manera ascendente o descendente utilizamos arrange():
#ascendente
data %>% arrange(valor)
## clase tipo valor
## 1 A uno 20
## 2 A uno 24
## 3 A uno 31
## 4 C dos 43
## 5 A uno 44
## 6 C dos 52
## 7 C dos 54
## 8 C dos 61
## 9 B uno 67
## 10 B uno 70
## 11 B dos 84
## 12 B dos 95
#descendente
data %>% arrange(desc(valor)) %>% head()
## clase tipo valor
## 1 B dos 95
## 2 B dos 84
## 3 B uno 70
## 4 B uno 67
## 5 C dos 61
## 6 C dos 54
Para agregar una nueva fila a la base de datos podemos utilizar add_row():
data %>% add_row(clase = "D", tipo = "tres", valor = 100)
## clase tipo valor
## 1 A uno 20
## 2 A uno 31
## 3 A uno 24
## 4 A uno 44
## 5 B uno 67
## 6 B uno 70
## 7 B dos 95
## 8 B dos 84
## 9 C dos 52
## 10 C dos 43
## 11 C dos 54
## 12 C dos 61
## 13 D tres 100
Otra caracterÃstica importante es el conteo, podrÃamos estar interesados, dado un conjunto de clases cual es su frecuencia absoluta, para esto utilizaremos count() el cual genera una variable que contiene dichas frecuencias.
data %>% count(tipo)
## # A tibble: 2 x 2
## tipo n
## <fct> <int>
## 1 dos 6
## 2 uno 6
En caso de tener NA dentro del dataframe y estemos interesados en omitir dichas filas podrÃamos omitirtas concatenando na.omit(): para esto agregaremos algunas filas:
dataNA<-data %>% add_row(clase = NA , tipo = "tres", valor = 100)
dataNA
## clase tipo valor
## 1 A uno 20
## 2 A uno 31
## 3 A uno 24
## 4 A uno 44
## 5 B uno 67
## 6 B uno 70
## 7 B dos 95
## 8 B dos 84
## 9 C dos 52
## 10 C dos 43
## 11 C dos 54
## 12 C dos 61
## 13 <NA> tres 100
ahora para omitir los NA utilizamos el na.omit().
dataNA %>% na.omit()
## clase tipo valor
## 1 A uno 20
## 2 A uno 31
## 3 A uno 24
## 4 A uno 44
## 5 B uno 67
## 6 B uno 70
## 7 B dos 95
## 8 B dos 84
## 9 C dos 52
## 10 C dos 43
## 11 C dos 54
## 12 C dos 61
Aunque es común que para la creación de variables solo se utiliza mutate() asà como sus derivaciones, la realidad es que al crear una variable nueva debemos utilizar lo ya aprendido hasta ahora.
Primero realizamos una variable sencilla, crearemos el logaritmo de la variable valor y su función 1 / valor, estos valores nos interesa guardarlos en una nueva base de datos:
data1<- data %>% mutate(logaritmo = log(valor), inverso = 1/valor)
data1
## clase tipo valor logaritmo inverso
## 1 A uno 20 2.995732 0.05000000
## 2 A uno 31 3.433987 0.03225806
## 3 A uno 24 3.178054 0.04166667
## 4 A uno 44 3.784190 0.02272727
## 5 B uno 67 4.204693 0.01492537
## 6 B uno 70 4.248495 0.01428571
## 7 B dos 95 4.553877 0.01052632
## 8 B dos 84 4.430817 0.01190476
## 9 C dos 52 3.951244 0.01923077
## 10 C dos 43 3.761200 0.02325581
## 11 C dos 54 3.988984 0.01851852
## 12 C dos 61 4.110874 0.01639344
Podemos utilizar ifelse() para crear variables según ciertas condiciones:
data1<-data1 %>% mutate(categorÃa = ifelse(logaritmo > 4, "Mayor", "Menor"))
Podemos utilizar varios ifelse()para agregar varias categorÃas dentro de la variable, para esto utilizaremos la función de pertenencia %in% en el caso que los datos sean contables:
data %>% mutate(categorÃa = ifelse(valor %in% 0:30, "0-30",
ifelse(valor %in% 31:60, "31-60",
ifelse(valor %in% 61:90, "61-90", "más de 90" ))))
## clase tipo valor categorÃa
## 1 A uno 20 0-30
## 2 A uno 31 31-60
## 3 A uno 24 0-30
## 4 A uno 44 31-60
## 5 B uno 67 61-90
## 6 B uno 70 61-90
## 7 B dos 95 más de 90
## 8 B dos 84 61-90
## 9 C dos 52 31-60
## 10 C dos 43 31-60
## 11 C dos 54 31-60
## 12 C dos 61 61-90
Podemos tambien renombrar las variables con la función rename():
data %>% rename(altura = valor)
## clase tipo altura
## 1 A uno 20
## 2 A uno 31
## 3 A uno 24
## 4 A uno 44
## 5 B uno 67
## 6 B uno 70
## 7 B dos 95
## 8 B dos 84
## 9 C dos 52
## 10 C dos 43
## 11 C dos 54
## 12 C dos 61
Supongamos que tenemos la siguiente fecha en nuestro dataframe 2020-04-11 podemos ver que el formato no es un dato temporal preguntando con str():
str("2020-04-11")
## chr "2020-04-11"
Como vemos es una variable tipo caracter. Para darle formato podemos guiarnos con la siguiente tabla:
| Formato | Implementación |
|---|---|
| %d | DÃa (número) |
| %a | DÃa (tres letras) |
| %A | DÃa (nombre completo) |
| %m | mes (número) |
| %b | mes (nombre abreviado) |
| %B | mes (nombre completo) |
| %y | año (dos dÃgitos) |
| %Y | año (cuatro dÃgitos) |
Supongamos que tenemos los siguientes datos de inicio y fin de algún evento.
inicio <- c("2020-01-06","2020-02-06","2020-01-06","2020-04-06",
"2020-05-06","2020-03-06","2020-02-06","2020-02-06",
"2020-01-06","2020-01-06","2020-02-06","2020-03-06")
fin <- c("20-05-jul","20-03-jul","20-06-jul","20-07-jul",
"20-09-jul","20-07-jul","20-04-jul","20-07-jul",
"20-05-jul","20-03-jul","20-03-jul","20-06-jul")
Para ver el formato de las nuevas variables usamos nuevamente str():
str(inicio)
## chr [1:12] "2020-01-06" "2020-02-06" "2020-01-06" "2020-04-06" ...
str(fin)
## chr [1:12] "20-05-jul" "20-03-jul" "20-06-jul" "20-07-jul" ...
Ambas son de tipo caracter, ahora demos el formato de fecha con as.Date():
inicio <- as.Date(inicio, format = "%Y-%d-%m")
fin <- as.Date(fin, format = "%y-%d-%b")
str(inicio)
## Date[1:12], format: "2020-06-01" "2020-06-02" "2020-06-01" "2020-06-04" "2020-06-05" ...
str(fin)
## Date[1:12], format: "2020-07-05" "2020-07-03" "2020-07-06" "2020-07-07" "2020-07-09" ...
Ahora ambas son fechas. PodrÃamos crear una nueva variable en nuestro dataframe por ejemplo, los dÃas que transcurrieron entre la fecha de inicio y fin.
data$inicio <- inicio
data$fin <- fin
data %>% mutate(dias = as.numeric(fin - inicio))
## clase tipo valor inicio fin dias
## 1 A uno 20 2020-06-01 2020-07-05 34
## 2 A uno 31 2020-06-02 2020-07-03 31
## 3 A uno 24 2020-06-01 2020-07-06 35
## 4 A uno 44 2020-06-04 2020-07-07 33
## 5 B uno 67 2020-06-05 2020-07-09 34
## 6 B uno 70 2020-06-03 2020-07-07 34
## 7 B dos 95 2020-06-02 2020-07-04 32
## 8 B dos 84 2020-06-02 2020-07-07 35
## 9 C dos 52 2020-06-01 2020-07-05 34
## 10 C dos 43 2020-06-01 2020-07-03 32
## 11 C dos 54 2020-06-02 2020-07-03 31
## 12 C dos 61 2020-06-03 2020-07-06 33
PodrÃamos generar una variable que sea una semana después de la fecha de inicio:
data %>% mutate(inicio2 = inicio + 7 )
## clase tipo valor inicio fin inicio2
## 1 A uno 20 2020-06-01 2020-07-05 2020-06-08
## 2 A uno 31 2020-06-02 2020-07-03 2020-06-09
## 3 A uno 24 2020-06-01 2020-07-06 2020-06-08
## 4 A uno 44 2020-06-04 2020-07-07 2020-06-11
## 5 B uno 67 2020-06-05 2020-07-09 2020-06-12
## 6 B uno 70 2020-06-03 2020-07-07 2020-06-10
## 7 B dos 95 2020-06-02 2020-07-04 2020-06-09
## 8 B dos 84 2020-06-02 2020-07-07 2020-06-09
## 9 C dos 52 2020-06-01 2020-07-05 2020-06-08
## 10 C dos 43 2020-06-01 2020-07-03 2020-06-08
## 11 C dos 54 2020-06-02 2020-07-03 2020-06-09
## 12 C dos 61 2020-06-03 2020-07-06 2020-06-10
En general es muy útil tener las fechas con su formato para crear diversas variables donde tengamos que manipular la variable tiempo.
PodrÃamos concatenar nuestra dataframe modificada para hacer gráficos sin necesidad de tenerla almacenada, esto nos da un ahorro de memoria. Usaremos el código anterior de ifelse() :
library(ggplot2)
data %>% mutate(categorÃa = ifelse(valor %in% 0:30, "0-30",
ifelse(valor %in% 31:60, "31-60",
ifelse(valor %in% 61:90, "61-90", "más de 90")))) %>%
ggplot(aes(x = categorÃa, y = valor, color = clase)) +
geom_point() +
labs(title = "Ejemplo de Gráfico")
Otro punto importante al manipular dataframes es lograr colocar los rownames extraÃdos del alguna columna de nuestro dataframe, crearemos para ilustrar esto otra variable:
data$pais <- c("MEX", "USA", "ARG", "ESP", "AUS", "HOL", "FRA", "JAP", "CHN", "RUS", "CAN", "COL")
data
## clase tipo valor inicio fin pais
## 1 A uno 20 2020-06-01 2020-07-05 MEX
## 2 A uno 31 2020-06-02 2020-07-03 USA
## 3 A uno 24 2020-06-01 2020-07-06 ARG
## 4 A uno 44 2020-06-04 2020-07-07 ESP
## 5 B uno 67 2020-06-05 2020-07-09 AUS
## 6 B uno 70 2020-06-03 2020-07-07 HOL
## 7 B dos 95 2020-06-02 2020-07-04 FRA
## 8 B dos 84 2020-06-02 2020-07-07 JAP
## 9 C dos 52 2020-06-01 2020-07-05 CHN
## 10 C dos 43 2020-06-01 2020-07-03 RUS
## 11 C dos 54 2020-06-02 2020-07-03 CAN
## 12 C dos 61 2020-06-03 2020-07-06 COL
Vamos a colocar estos nombres de paÃses como un rowname de nuestro dataframe:
rownames(data) <- data$pais
data
## clase tipo valor inicio fin pais
## MEX A uno 20 2020-06-01 2020-07-05 MEX
## USA A uno 31 2020-06-02 2020-07-03 USA
## ARG A uno 24 2020-06-01 2020-07-06 ARG
## ESP A uno 44 2020-06-04 2020-07-07 ESP
## AUS B uno 67 2020-06-05 2020-07-09 AUS
## HOL B uno 70 2020-06-03 2020-07-07 HOL
## FRA B dos 95 2020-06-02 2020-07-04 FRA
## JAP B dos 84 2020-06-02 2020-07-07 JAP
## CHN C dos 52 2020-06-01 2020-07-05 CHN
## RUS C dos 43 2020-06-01 2020-07-03 RUS
## CAN C dos 54 2020-06-02 2020-07-03 CAN
## COL C dos 61 2020-06-03 2020-07-06 COL
Otra ventaja de utilizar dplyr es el uso de inner_join() y full_join() de manera similar a la forma en como se hacen consultas en sql. para esto crearemos una segunda base de datos:
x <- c(2,4,8,16,32,64,128,64,32,8,4,2)
y <- c(3,6,23,14,16,23,17,37,42,34,25,12)
pais <- c("MEX", "USA", "BEL", "ESP", "AUS", "HOL", "FRA", "JAP", "CHN", "RUS", "CAN", "NOR")
data2<- data.frame(x,y,pais)
data2
## x y pais
## 1 2 3 MEX
## 2 4 6 USA
## 3 8 23 BEL
## 4 16 14 ESP
## 5 32 16 AUS
## 6 64 23 HOL
## 7 128 17 FRA
## 8 64 37 JAP
## 9 32 42 CHN
## 10 8 34 RUS
## 11 4 25 CAN
## 12 2 12 NOR
Ahora vamos a unir ambas bases, notemos que ambas cuentan con la variable paÃs, esta será nuestra variable utilizada para enlazarlas:
full_join(data, data2, by = "pais")
## Warning: Column `pais` joining character vector and factor, coercing into
## character vector
## clase tipo valor inicio fin pais x y
## 1 A uno 20 2020-06-01 2020-07-05 MEX 2 3
## 2 A uno 31 2020-06-02 2020-07-03 USA 4 6
## 3 A uno 24 2020-06-01 2020-07-06 ARG NA NA
## 4 A uno 44 2020-06-04 2020-07-07 ESP 16 14
## 5 B uno 67 2020-06-05 2020-07-09 AUS 32 16
## 6 B uno 70 2020-06-03 2020-07-07 HOL 64 23
## 7 B dos 95 2020-06-02 2020-07-04 FRA 128 17
## 8 B dos 84 2020-06-02 2020-07-07 JAP 64 37
## 9 C dos 52 2020-06-01 2020-07-05 CHN 32 42
## 10 C dos 43 2020-06-01 2020-07-03 RUS 8 34
## 11 C dos 54 2020-06-02 2020-07-03 CAN 4 25
## 12 C dos 61 2020-06-03 2020-07-06 COL NA NA
## 13 <NA> <NA> NA <NA> <NA> BEL 8 23
## 14 <NA> <NA> NA <NA> <NA> NOR 2 12
Al usar full_join() se unen integras ambas bases, como vemos hay dos variables que no coinciden en cada base por lo que nos genera NA. Para evitarlo utilizaremos ìnner_join():
data %>% inner_join(data2, by = "pais")
## Warning: Column `pais` joining character vector and factor, coercing into
## character vector
## clase tipo valor inicio fin pais x y
## 1 A uno 20 2020-06-01 2020-07-05 MEX 2 3
## 2 A uno 31 2020-06-02 2020-07-03 USA 4 6
## 3 A uno 44 2020-06-04 2020-07-07 ESP 16 14
## 4 B uno 67 2020-06-05 2020-07-09 AUS 32 16
## 5 B uno 70 2020-06-03 2020-07-07 HOL 64 23
## 6 B dos 95 2020-06-02 2020-07-04 FRA 128 17
## 7 B dos 84 2020-06-02 2020-07-07 JAP 64 37
## 8 C dos 52 2020-06-01 2020-07-05 CHN 32 42
## 9 C dos 43 2020-06-01 2020-07-03 RUS 8 34
## 10 C dos 54 2020-06-02 2020-07-03 CAN 4 25
Podemos concatenar esto ahora con un gráfico:
data %>% inner_join(data2, by = "pais") %>%
ggplot(aes(x = x, y = y, color = clase)) +
geom_point(aes(size = valor ), alpha = 0.5)+
scale_size(range=c(.1,8))+
labs(title = "Ejemplo de Gráfico")
## Warning: Column `pais` joining character vector and factor, coercing into
## character vector
Existen muchas más funciones de dplyr pero considero que estas son las más utilizadas. Ahora pasemos a un caso real. La web https://ourworldindata.org/coronavirus-data recopila información de todo el mundo sobre el estado actual de la pandemia de covid19, para esto importaremos la base de datos de su web:
library(readr)
covid19 <- read.csv(url("https://covid.ourworldindata.org/data/owid-covid-data.csv"))
La base contiene información diaria sobre 212 paÃses del mundo durante el 2020. Estas notas se elaboraron el 6 de junio de 2020 por lo que aun no hemos visto el pico de la pandemia.
PodrÃamos estar interesado en conocer la incidencia de contagio, es decir, los casos totales por cada 100 mil habitantes pero solo nos interesa para los paÃses que actualmente tiene más de 50 mil casos confirmados. Además solo nos interesa analizar los paÃses que reportaron datos al 5 de junio de 2020 y a qué región pertenecen.
Primero aplicaremos un filtro para sacar los datos correspondientes al 05 de junio de 2020. Después solo seleccionaremos el total de casos confirmados, la población total, continente, paÃs y su código.
covid19 %>% filter(date == "2020-06-05") %>% select(location, total_cases, population, iso_code, continent) %>% head()
## location total_cases population iso_code continent
## 1 Afghanistan 18054 38928341 AFG Asia
## 2 Albania 1197 2877800 ALB Europe
## 3 Algeria 9831 43851043 DZA Africa
## 4 Andorra 852 77265 AND Europe
## 5 Angola 86 32866268 AGO Africa
## 6 Anguilla 3 15002 AIA North America
Ahora concatenaremos un filtro para tener solo los paÃses con más de 50 mil casos confirmados y crearemos una nueva variable llamada incidencia que será el total de casos por cada 100 mil habitantes. Finalmente quitaremos World que muestra el total mundial:
covid19 %>% filter(date == "2020-06-05") %>% select(location, total_cases, population, iso_code, continent) %>% filter(total_cases >= 50000) %>%
mutate(incidencia = total_cases*100000/population) %>% filter(location!= "World") %>%
head()
## location total_cases population iso_code continent incidencia
## 1 Bangladesh 57563 164689383 BGD Asia 34.952466
## 2 Belgium 58767 11589616 BEL Europe 507.065980
## 3 Brazil 614941 212559409 BRA South America 289.303119
## 4 Canada 93715 37742157 CAN North America 248.303244
## 5 Chile 118292 19116209 CHL South America 618.804701
## 6 China 84171 1439323774 CHN Asia 5.847955
Finalmente lo visualizaremos con un gráfico de barras:
library(hrbrthemes)
covid19 %>% filter(date == "2020-06-05") %>% select(location, total_cases, population, iso_code, continent) %>% filter(total_cases >= 50000) %>%
mutate(incidencia = total_cases*100000/population) %>%
filter(location!= "World") %>%
ggplot(aes(x = reorder(iso_code, + incidencia), y = incidencia, fill = continent)) +
geom_bar(stat='identity')+
theme_ipsum_rc()+
coord_flip() +
labs(title = "Incidencia de COVID19 en el mundo",
subtitle = "PaÃses con más de 50 mil casos confirmados",
x = "",
y = "Incidencia",
caption = "Elaboración propia con datos de \n https://ourworldindata.org/coronavirus-data al 6 de junio de 2020")
Hagamos otro ejemplo. PodrÃamos estar interesados en conocer la relación entre la incidencia de covid19 con el PIB percápita de cada paÃs y eso ponderado por el total de defunciones. Sin embargo queremos que contenga una categorÃa respecto a la densidad de población dividida en alta, media y baja. Primero seleccionamos las variables:
covid19 %>% filter(date == "2020-06-05") %>% select(iso_code, total_cases, population, population_density, gdp_per_capita, total_deaths) %>% na.omit() %>% head()
## iso_code total_cases population population_density gdp_per_capita
## 1 AFG 18054 38928341 54.422 1803.987
## 2 ALB 1197 2877800 104.871 11803.431
## 3 DZA 9831 43851043 17.348 13913.839
## 5 AGO 86 32866268 23.890 5819.495
## 7 ATG 26 97928 231.845 21490.943
## 8 ARG 19255 45195777 16.177 18933.907
## total_deaths
## 1 300
## 2 33
## 3 681
## 5 4
## 7 3
## 8 588
Ahora crearemos la variable categórica para la densidad de población, primero veamos sus cuartiles omitiendo los NA:
quantile(covid19$population_density, na.rm = TRUE)
## 0% 25% 50% 75% 100%
## 0.137 41.285 93.105 227.322 19347.500
Tomaremos el primer cuartil como baja, el segundo como medio y el tercero como alta densidad.
covid19 %>% filter(date == "2020-06-05") %>% select(iso_code, total_cases, population, population_density, gdp_per_capita, total_deaths) %>% na.omit() %>%
mutate(incidencia = total_cases*100000/population) %>%
mutate(densidad = ifelse(population_density <= 41.285, "Baja",
ifelse(population_density <= 277.322, "Media","Alta"))) %>%
head()
## iso_code total_cases population population_density gdp_per_capita
## 1 AFG 18054 38928341 54.422 1803.987
## 2 ALB 1197 2877800 104.871 11803.431
## 3 DZA 9831 43851043 17.348 13913.839
## 4 AGO 86 32866268 23.890 5819.495
## 5 ATG 26 97928 231.845 21490.943
## 6 ARG 19255 45195777 16.177 18933.907
## total_deaths incidencia densidad
## 1 300 46.3775222 Media
## 2 33 41.5942734 Media
## 3 681 22.4190791 Baja
## 4 4 0.2616665 Baja
## 5 3 26.5501185 Media
## 6 588 42.6035379 Baja
Realicemos ahora un gráfico de puntos:
options(scipen=999) #Quitar notación cientÃfica
covid19 %>% filter(date == "2020-06-05") %>% select(iso_code, total_cases, population, population_density, gdp_per_capita, total_deaths) %>% na.omit() %>%
mutate(incidencia = total_cases*100000/population) %>%
mutate(densidad = ifelse(population_density <= 41.285, "Baja",
ifelse(population_density <= 277.322, "Media","Alta"))) %>%
ggplot(aes(x = gdp_per_capita, y = incidencia, fill = densidad, color=densidad))+
geom_point(aes(size = total_deaths), alpha = 0.5)+
scale_size(range=c(.4, 10), name = "Total de defunciones")+
theme_ipsum_rc()+
labs(x = "GDP percápita",
y = "Incidencia",
title = "Comparativa entre Incidencia y GDP percápita",
subtitle = "Clasificado por densidad poblacional y total de muertes",
caption = "Elaboración propia con datos de https://ourworldindata.org/.
Actualización al 5 de junio de 2020")