Capítulo 4 Transformación de datos con Tidyverse
- En esta sección hablo sobre algunas nociones básicas de transformación de datos.
- Puedes acceder a una clase en video que realicé sobre este tema en el siguiente link.
4.1 Importar un data frame en R
En vez de escribir nuestro directorio como data//covid//owid-covid-data.csv
, podemos usar lo siguiente gracias al package here
:
# install.packages("vroom")
# install.packages("here")
<- vroom::vroom(here::here("data", "covid", "owid-covid-data.csv")) data
El package
vroom
acepta cualquier formato de archivo.
4.2 El package magrittr
install.packages("maggritr")
require(magrittr)
- Nos permite usar el famoso “pipe”
%>%
. - Es una forma más moderna y ordenada para programar en R.
- Usa la memoria del sistema de forma más eficiente.
- Se hace con
CTRL o CMD
+SHIFT
+M
. - Su uso más común es para explorar bases de datos.
4.2.1 Ejemplos
4.2.1.1 \(\,\)
En vez de hacer:
apply((matrix(1:100, ncol = 2)), 2, mean)
[1] 25.5 75.5
Podemos hacer:
1:100 %>% # Crear vector del 1 al 100
matrix(ncol = 2) %>% # Crear una matriz con 2 columnas
apply(2, mean) # Aplicar función mean a columnas
[1] 25.5 75.5
Se ve mucho más ✨ ordenado ✨.
4.2.1.2 \(\,\)
Esto nos dará error
1:5 %>%
* 5 %>%
mean()
Debemos hacer:
1:5 %>%
"*" (5) %>%
mean()
[1] 15
Admite operadores como “+,” “-,” "*" y “/.” El valor numérico debe ir siempre entre paréntesis.
4.2.2 \(\,\)
Podemos crear una variable y después realizarle una modificación.
<- 1:10 %>%
suma_y_media "+" (50)
suma_y_media
[1] 51 52 53 54 55 56 57 58 59 60
Ahora calculamos la media:
<- suma_y_media %>%
suma_y_media mean()
suma_y_media
[1] 55.5
4.3 El package dplyr
install.packages("dplyr")
require(dplyr)
- Es una potente herramienta en conjunto a
magrittr
para analizar datos en R. - Sus principales funciones son
filter
,group_by
,summarize
,mutate
,arrange
yselect
.
4.3.1 filter
Sirve para indicarle a R que seleccione solo las filas que cumplan la condición que establezcamos. Ejemplo:
Para empezar, veamos el tipo de variables de la base de datos iris
.
str(iris)
'data.frame': 150 obs. of 5 variables:
$ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
$ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
$ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
$ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
$ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
Ahora usemos la función filter
para ver tuplas que solo tengan la variable Sepal.Length
mayor o igual a 7.4:
<- iris %>%
filtro_Sepal.Length filter(Sepal.Length >= 7.4)
%>%
filtro_Sepal.Length ::reactable() # Para visualizar tablas de forma interactiva reactable
4.3.2 group_by
& summarize
- Ambas deben ser usadas en conjunto.
group_by
: Sirve para agrupar según una variable categórica. Puede recibir más de una variable, según la necesidad que se tenga.summarize
: Para mostrar la información que necesitamos ver después de usargroup_by
.
Ejemplo:
Veamos la media de Sepal.Length
y Sepal.Width
para cada especie.
<- iris %>%
group_by_Species group_by(Species) %>% # Agrupamos según especie
summarize(mean_Sepal.Width = mean(Sepal.Width),
mean_Sepal.Length = mean(Sepal.Length)) # Información que necesitamos ver de cada Especie
%>%
group_by_Species ::reactable() # Vizualizamos reactable
4.3.3 mutate
Podemos crear una variable nueva en la base de datos a partir de variables ya existentes. Ejemplo:
Creamos una base de datos que en su última columna tenga información sobre la suma de Sepal.Length
y Sepal.Width
para cada tupla.
<- iris %>%
mutate_iris mutate(Sepal.Sum = Sepal.Length + Sepal.Width) # Creamos una variable Sepal.Sum
%>%
mutate_iris ::reactable() reactable
Vemos que se creo una variable nueva al final de la base.
4.3.4 arrange
- Sirve para ordenar las columnas de la base de datos en orden ascendente o descendente.
- Se puede seleccionar más de una variable, según la necesidad que se tenga.
- Para ordenar las columnas de la base es necesario llamar a la función
desc
.
Ejemplo:
- Para ordenar la columna de la variable
Sepal.Width
en orden ascendente:
<- iris %>%
arrange_asc arrange(Sepal.Width)
%>%
arrange_asc ::reactable() reactable
- Ordenar la columna
Species
en orden descendente:
<- iris %>%
arrange_desc arrange(desc(Species))
%>%
arrange_desc ::reactable() reactable
4.3.5 select
- Sirve para seleccionar o no seleccionar variables de la base de datos.
- Para no seleccionar una variable hay que anteponer un signo
!
y un vector con los nombres de las variables.
Ejemplo:
- Para seleccionar variables:
<- iris %>%
select_Sepal select(Sepal.Length, Sepal.Width) # Alternativamente select(matches("Sepal"))
%>%
select_Sepal ::reactable() reactable
- Para no seleccionar variables:
<- iris %>%
not_select_Sepal select(!c(Sepal.Length, Sepal.Width)) # Alternativamente select(!matches("Sepal"))
%>%
not_select_Sepal ::reactable() reactable
Podemos ver que están todas las variables menos las que escribimos en la función
select
.
4.4 Actividades
4.4.1 \(\,\)
Cargue la base de datos con información sobre el coronavirus desde https://ourworldindata.org/coronavirus-testing. Luego muestre el tipo de cada variable de la base.
4.4.2 \(\,\)
¿Cuál es la media de casos en Chile en el mes de enero de 2021?
4.4.3 \(\,\)
Genere una tabla con la cantidad de test hechos en los países de América del Sur en el último mes, ordenado de menor a mayor.
4.4.4 \(\,\)
¿Cuál es el país con mayor cantidad de casos por millón de habitantes en Europa desde el inicio de la pandemia? ¿Y el segundo?
4.4.5 \(\,\)
Muestre información sobre la cantidad de casos que han habido en las últimas 2 semanas en cada continente.
4.5 Solución de Actividades
4.5.1 Actividad 1
require(ggplot2); require(gghighlight); require(magrittr); require(dplyr)
<- vroom::vroom(here::here("data", "covid", "owid-covid-data.csv"))
data
%>%
data str()
spec_tbl_df [78,664 x 59] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
$ iso_code : chr [1:78664] "AFG" "AFG" "AFG" "AFG" ...
$ continent : chr [1:78664] "Asia" "Asia" "Asia" "Asia" ...
$ location : chr [1:78664] "Afghanistan" "Afghanistan" "Afghanistan" "Afghanistan" ...
$ date : Date[1:78664], format: "2020-02-24" ...
$ total_cases : num [1:78664] 1 1 1 1 1 1 1 1 2 4 ...
$ new_cases : num [1:78664] 1 0 0 0 0 0 0 0 1 2 ...
$ new_cases_smoothed : num [1:78664] NA NA NA NA NA 0.143 0.143 0 0.143 0.429 ...
$ total_deaths : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ new_deaths : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ new_deaths_smoothed : num [1:78664] NA NA NA NA NA 0 0 0 0 0 ...
$ total_cases_per_million : num [1:78664] 0.026 0.026 0.026 0.026 0.026 0.026 0.026 0.026 0.051 0.103 ...
$ new_cases_per_million : num [1:78664] 0.026 0 0 0 0 0 0 0 0.026 0.051 ...
$ new_cases_smoothed_per_million : num [1:78664] NA NA NA NA NA 0.004 0.004 0 0.004 0.011 ...
$ total_deaths_per_million : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ new_deaths_per_million : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ new_deaths_smoothed_per_million : num [1:78664] NA NA NA NA NA 0 0 0 0 0 ...
$ reproduction_rate : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ icu_patients : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ icu_patients_per_million : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ hosp_patients : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ hosp_patients_per_million : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ weekly_icu_admissions : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ weekly_icu_admissions_per_million : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ weekly_hosp_admissions : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ weekly_hosp_admissions_per_million : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ new_tests : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ total_tests : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ total_tests_per_thousand : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ new_tests_per_thousand : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ new_tests_smoothed : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ new_tests_smoothed_per_thousand : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ positive_rate : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ tests_per_case : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ tests_units : chr [1:78664] NA NA NA NA ...
$ total_vaccinations : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ people_vaccinated : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ people_fully_vaccinated : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ new_vaccinations : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ new_vaccinations_smoothed : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ total_vaccinations_per_hundred : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ people_vaccinated_per_hundred : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ people_fully_vaccinated_per_hundred : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ new_vaccinations_smoothed_per_million: num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ stringency_index : num [1:78664] 8.33 8.33 8.33 8.33 8.33 ...
$ population : num [1:78664] 38928341 38928341 38928341 38928341 38928341 ...
$ population_density : num [1:78664] 54.4 54.4 54.4 54.4 54.4 ...
$ median_age : num [1:78664] 18.6 18.6 18.6 18.6 18.6 18.6 18.6 18.6 18.6 18.6 ...
$ aged_65_older : num [1:78664] 2.58 2.58 2.58 2.58 2.58 ...
$ aged_70_older : num [1:78664] 1.34 1.34 1.34 1.34 1.34 ...
$ gdp_per_capita : num [1:78664] 1804 1804 1804 1804 1804 ...
$ extreme_poverty : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ cardiovasc_death_rate : num [1:78664] 597 597 597 597 597 ...
$ diabetes_prevalence : num [1:78664] 9.59 9.59 9.59 9.59 9.59 9.59 9.59 9.59 9.59 9.59 ...
$ female_smokers : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ male_smokers : num [1:78664] NA NA NA NA NA NA NA NA NA NA ...
$ handwashing_facilities : num [1:78664] 37.7 37.7 37.7 37.7 37.7 ...
$ hospital_beds_per_thousand : num [1:78664] 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 ...
$ life_expectancy : num [1:78664] 64.8 64.8 64.8 64.8 64.8 ...
$ human_development_index : num [1:78664] 0.511 0.511 0.511 0.511 0.511 0.511 0.511 0.511 0.511 0.511 ...
- attr(*, "spec")=
.. cols(
.. iso_code = col_character(),
.. continent = col_character(),
.. location = col_character(),
.. date = col_date(format = ""),
.. total_cases = col_double(),
.. new_cases = col_double(),
.. new_cases_smoothed = col_double(),
.. total_deaths = col_double(),
.. new_deaths = col_double(),
.. new_deaths_smoothed = col_double(),
.. total_cases_per_million = col_double(),
.. new_cases_per_million = col_double(),
.. new_cases_smoothed_per_million = col_double(),
.. total_deaths_per_million = col_double(),
.. new_deaths_per_million = col_double(),
.. new_deaths_smoothed_per_million = col_double(),
.. reproduction_rate = col_double(),
.. icu_patients = col_double(),
.. icu_patients_per_million = col_double(),
.. hosp_patients = col_double(),
.. hosp_patients_per_million = col_double(),
.. weekly_icu_admissions = col_double(),
.. weekly_icu_admissions_per_million = col_double(),
.. weekly_hosp_admissions = col_double(),
.. weekly_hosp_admissions_per_million = col_double(),
.. new_tests = col_double(),
.. total_tests = col_double(),
.. total_tests_per_thousand = col_double(),
.. new_tests_per_thousand = col_double(),
.. new_tests_smoothed = col_double(),
.. new_tests_smoothed_per_thousand = col_double(),
.. positive_rate = col_double(),
.. tests_per_case = col_double(),
.. tests_units = col_character(),
.. total_vaccinations = col_double(),
.. people_vaccinated = col_double(),
.. people_fully_vaccinated = col_double(),
.. new_vaccinations = col_double(),
.. new_vaccinations_smoothed = col_double(),
.. total_vaccinations_per_hundred = col_double(),
.. people_vaccinated_per_hundred = col_double(),
.. people_fully_vaccinated_per_hundred = col_double(),
.. new_vaccinations_smoothed_per_million = col_double(),
.. stringency_index = col_double(),
.. population = col_double(),
.. population_density = col_double(),
.. median_age = col_double(),
.. aged_65_older = col_double(),
.. aged_70_older = col_double(),
.. gdp_per_capita = col_double(),
.. extreme_poverty = col_double(),
.. cardiovasc_death_rate = col_double(),
.. diabetes_prevalence = col_double(),
.. female_smokers = col_double(),
.. male_smokers = col_double(),
.. handwashing_facilities = col_double(),
.. hospital_beds_per_thousand = col_double(),
.. life_expectancy = col_double(),
.. human_development_index = col_double()
.. )
- attr(*, "problems")=<externalptr>
4.5.2 Actividad 2
<- data %>%
media_casos_chile_enero_2021 filter(location == "Chile") %>%
filter(date >= "2021-01-01" & date <= "2021-01-31") %>%
group_by(location) %>%
summarize(media_casos = mean(new_cases, na.rm = TRUE))
%>%
media_casos_chile_enero_2021 ::reactable() reactable
4.5.3 Actividad 3
<- data %>%
test_latinoamerica_ultimo_mes filter(continent == "South America") %>%
filter(date >= "2021-01-10" & date <= "2021-02-10") %>%
filter(!is.na(new_tests)) %>%
group_by(location) %>%
summarize(total_test = sum(new_tests)) %>%
arrange(total_test)
%>%
test_latinoamerica_ultimo_mes ::reactable() reactable
4.5.4 Actividad 4
<- data %>%
paises_europa_xmill filter(continent == "Europe") %>%
filter(!is.na(new_cases_per_million)) %>%
group_by(location) %>%
summarize(cases_per_million = sum(new_cases_per_million)) %>%
arrange(desc(cases_per_million))
%>%
paises_europa_xmill ::reactable() reactable
4.5.5 Actividad 5
<- data %>%
casos_contientes_2_semanas filter(date >= "2021-01-27" & date <= "2021-02-10") %>%
filter(!is.na(new_cases)) %>%
group_by(continent) %>%
summarize(casos = sum(new_cases))
%>%
casos_contientes_2_semanas ::reactable() reactable