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")
data <- vroom::vroom(here::here("data", "covid", "owid-covid-data.csv"))

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.

suma_y_media <- 1:10 %>%
    "+" (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 y select.

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:

filtro_Sepal.Length <- iris %>% 
    filter(Sepal.Length >= 7.4)

filtro_Sepal.Length %>%
    reactable::reactable() # Para visualizar tablas de forma interactiva

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 usar group_by.

Ejemplo:

Veamos la media de Sepal.Length y Sepal.Width para cada especie.

group_by_Species <- iris %>% 
    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::reactable() # Vizualizamos

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.

mutate_iris <- 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:
arrange_asc <- iris %>% 
    arrange(Sepal.Width)

arrange_asc %>% 
    reactable::reactable()
  • Ordenar la columna Species en orden descendente:
arrange_desc <- iris %>%  
    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:
select_Sepal <- iris %>% 
    select(Sepal.Length, Sepal.Width) # Alternativamente select(matches("Sepal"))

select_Sepal %>% 
    reactable::reactable()
  • Para no seleccionar variables:
not_select_Sepal <- iris %>% 
    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)

data <- vroom::vroom(here::here("data", "covid", "owid-covid-data.csv"))

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

media_casos_chile_enero_2021 <- data %>% 
    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

test_latinoamerica_ultimo_mes <- data %>% 
    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

paises_europa_xmill <- data %>%
    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

casos_contientes_2_semanas <- data %>% 
    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()