Tidyverse

Resumen

Tidyverse es una colección de paquetes de R enfocados en ciencia de datos, los cuales “comparten filosofía de diseño, gramática y estructuras de datos”, de acuerdo con el sitio web de la iniciativa. El concepto de Tidyverse fue introducido por Hadley Wickham, quien también programó varios de sus paquetes.

El núcleo de Tidyverse está compuesto por ocho paquetes base, los cuales proveen las funcionalidades utilizadas más frecuentemente en análisis de datos. Hay otros paquetes para tareas más especifícas relacionadas con importación, limpieza y modelado de datos, entre otras áreas. Los paquetes de Tidyverse son de los más descargados, entre la totalidad de paquetes de R.

En esta lección, se explican algunos de los principales paquetes de Tidyverse.

Trabajo previo

Lea los capítulos del 1 al 21 de Wickhan, H. & Grolemund, G. (2018). R for Data Science: Import, Tidy, Transform, Visualize, and Model Data.

Preparativos

Carga de paquetes

# dplyr
library(dplyr)

Conjuntos de datos utilizados en los ejemplos

Datos hidrológicos
Este conjunto de datos contiene mediciones de caudal en varios ríos de Costa Rica.

# Carga de datos desde un archivo CSV
rios <-
  read.csv(file = 'https://raw.githubusercontent.com/tpb728O-programaciongeoespacialr/2021ii/main/datos/hidrologia/fdc/fdc.csv')

Casos de covid en Costa Rica
Este conjunto de datos es publicado por el Ministerio de Salud de Costa Rica. Contiene un registro por día con las estadísticas de casos positivos, fallecidos, activos y recuperados.

# Carga de datos desde un archivo CSV
covid <- 
  read.csv(
    file='https://raw.githubusercontent.com/tpb728O-programaciongeoespacialr/2021ii/main/datos/minsalud/covid/ultimafecha_CSV_GENERAL.csv', 
    sep = ","
  )
# Despliegue de los datos
View(cr_covid19)

Datos tidy

Los paquetes de Tidyverse trabajan con datos tidy (i.e. ordenados, organizados), un concepto también introducido por Hadley Wickham y que se está relacionado con la organización de los datos en estructuras rectangulares de filas y columnas, similares a las tablas o matrices.

Según Wickham, los datos tidy deben cumplir con tres características:

  1. Cada variable debe tener su propia columna.
  2. Cada observación debe tener su propia fila.
  3. Cada valor debe tener su propia celda.

Estas características se ilustran en la figura 1.

Figura 1: Datos tidy. Imagen de Hadley Wickham (https://r4ds.had.co.nz/tidy-data.html)

El empleo de este modelo de datos uniforme en todos los paquetes de Tidyverse posibilita aprender y usar sus funciones con mayor facilidad. Además, permite invertir menos esfuerzo en lidiar con diferentes modelos de datos y así dedicar más tiempo y esfuerzo en los problemas de análisis a resolver.

El paquete dplyr

El paquete dplyr de Tidyverse es descrito como una “gramática para la manipulación de datos, la cual proporciona un conjunto consistente de verbos que ayuda a solucionar los retos de manipulación de datos más comunes”. Los principales “verbos” (i.e. funciones) de esta gramática son:

Todas estas operaciones pueden combinarse con la función group_by(), la cual ejecuta cualquiera de las operaciones anteriores “en grupo”. Además, dplyr proporciona funciones adicionales para tareas más específicas.

Todas las funciones de dplyr trabajan de manera similar:

  1. El primer argumento es un data frame. Puede omitirse si la función recibe el data frame a través del operador pipe.
  2. Los argumentos siguientes describen que hacer con el data frame, utilizando los nombres de las variables (sin comillas).
  3. El resultado es un nuevo data frame.

Las funciones de dplyr pueden encadenarse a través del operador pipe (%>%) (tubo), para formar pipelines (tuberías). En este contexto, un pipeline consiste de una cadena de procesos conectados de forma tal que la salida de cada proceso de la cadena es la entrada del próximo. Esto permite la comunicación y sincronización entre los procesos.

La función mutate()

La función mutate() crea nuevas variables en un data frame, las cuales se expresan como funciones de variables existentes. También puede utilizarse para recalcular una variable ya existente.

En el siguiente bloque de código, se utiliza mutate() para crear una nueva variable en el data frame de ríos. Se utilizan también otras funciones para renombrar las columnas y desplegar los datos.

# Despliegue de la estructura del data frame
str(rios)
'data.frame':   3845 obs. of  3 variables:
 $ Tiempo             : chr  "6/22/1973" "6/23/1973" "6/24/1973" "6/25/1973" ...
 $ Pandora.mm..637km2.: num  7.46 6.17 6.32 7.8 7.72 7.83 5.02 3.84 3.21 2.77 ...
 $ Banano.mm..90km2.  : num  21 14.8 27.6 19.7 15.2 ...
# Despliegue de los primeros registros
slice_head(rios, n = 5)
     Tiempo Pandora.mm..637km2. Banano.mm..90km2.
1 6/22/1973                7.46             21.02
2 6/23/1973                6.17             14.78
3 6/24/1973                6.32             27.65
4 6/25/1973                7.80             19.68
5 6/26/1973                7.72             15.17
# Cambio de nombre de las columnas mediante rename()
rios <-
  rios %>%
  rename(fecha = Tiempo,
         pandora = Pandora.mm..637km2.,
         banano = Banano.mm..90km2.)

# Conversión de una columna a tipo Date y creación de una nueva columna
rios <-
  rios %>%
  mutate(fecha = as.Date(fecha, format = "%m/%d/%Y"),
         promedio = (pandora + banano) / 2)

# Verificación de los cambios en la estructura del data frame
str(rios)
'data.frame':   3845 obs. of  4 variables:
 $ fecha   : Date, format: "1973-06-22" ...
 $ pandora : num  7.46 6.17 6.32 7.8 7.72 7.83 5.02 3.84 3.21 2.77 ...
 $ banano  : num  21 14.8 27.6 19.7 15.2 ...
 $ promedio: num  14.2 10.5 17 13.7 11.4 ...
# Visualización de los valores de la nueva columna
slice_head(rios, n = 5)
       fecha pandora banano promedio
1 1973-06-22    7.46  21.02   14.240
2 1973-06-23    6.17  14.78   10.475
3 1973-06-24    6.32  27.65   16.985
4 1973-06-25    7.80  19.68   13.740
5 1973-06-26    7.72  15.17   11.445

La función select()

La función select() selecciona variables (i.e. columnas) de un data frame con base en sus nombres.

En el siguiente bloque de código, se utiiza select() para seleccionar un conjunto de variables del data frame de COVID-19 en Costa Rica. El resultado se guarda en un nuevo data frame.

# Selección, renombramiento y conversión de columnas
covid_columnas_seleccionadas <-
  covid %>%
  select(FECHA, muj_posi, hom_posi) %>%
  rename(
    fecha = FECHA,
    positivos_mujeres = muj_posi,
    positivos_hombres = hom_posi
  ) %>%
  mutate(fecha = as.Date(fecha, format = "%d/%m/%Y"))

# Despliegue de una muestra aleatoria de los registros
slice_sample(covid_columnas_seleccionadas, n = 5)
       fecha positivos_mujeres positivos_hombres
1 2021-09-11            245467            246863
2 2021-02-07             97142            100083
3 2020-03-09                NA                NA
4 2020-10-28             51382             55171
5 2020-06-23              1049              1319

La función filter()

La función filter() selecciona observaciones (i.e. filas) de un data frame con base en sus valores.

En el siguiente bloque de código, se utiliza filter() para filtrar el data frame de COVID-19 en Costa Rica. El resultado se guarda en un nuevo data frame.

# Selección, renombramiento, conversión de columnas y filtrado
covid_filtrado <-
  covid %>%
  select(FECHA, nue_posi) %>%
  rename(fecha = FECHA, positivos_nuevos = nue_posi) %>%
  mutate(fecha = as.Date(fecha, format = "%d/%m/%Y")) %>%
  filter(positivos_nuevos >= 2500)

# Despliegue del data frame con los resultados
covid_filtrado
        fecha positivos_nuevos
1  2021-04-29             2781
2  2021-04-30             2609
3  2021-05-05             2555
4  2021-05-06             2559
5  2021-05-12             3173
6  2021-05-13             3039
7  2021-05-14             2815
8  2021-05-15             2795
9  2021-05-19             2900
10 2021-05-20             2812
11 2021-05-21             2587
12 2021-05-26             2587
13 2021-08-25             2619
14 2021-08-26             2706
15 2021-08-27             2787
16 2021-08-31             2581
17 2021-09-01             2848
18 2021-09-02             2991
19 2021-09-03             2750
20 2021-09-07             2956
21 2021-09-08             2884
22 2021-09-09             2975
23 2021-09-10             2825
24 2021-09-11             2546

La función arrange()

La función arrange() cambia el orden de las observaciones (i.e. filas) de un dataframe.

En el siguiente bloque de código, se utiliza arrange() para ordenar el data frame de COVID-19 en Costa Rica, después de filtrarlo. El resultado se guarda en un nuevo data frame.

# Selección, renombramiento, filtrado y conversión de columnas
covid_filtrado_ordenado_x_positivos_nuevos <-
  covid %>%
  select(FECHA, nue_posi) %>%
  rename(fecha = FECHA, positivos_nuevos = nue_posi) %>%
  mutate(fecha = as.Date(fecha, format = "%d/%m/%Y")) %>%
  filter(positivos_nuevos >= 2500) %>%
  arrange(desc(positivos_nuevos))

# Despliegue del data frame con los resultados
covid_filtrado_ordenado_x_positivos_nuevos
        fecha positivos_nuevos
1  2021-05-12             3173
2  2021-05-13             3039
3  2021-09-02             2991
4  2021-09-09             2975
5  2021-09-07             2956
6  2021-05-19             2900
7  2021-09-08             2884
8  2021-09-01             2848
9  2021-09-10             2825
10 2021-05-14             2815
11 2021-05-20             2812
12 2021-05-15             2795
13 2021-08-27             2787
14 2021-04-29             2781
15 2021-09-03             2750
16 2021-08-26             2706
17 2021-08-25             2619
18 2021-04-30             2609
19 2021-05-21             2587
20 2021-05-26             2587
21 2021-08-31             2581
22 2021-05-06             2559
23 2021-05-05             2555
24 2021-09-11             2546

La función summarise()

La función summarise() agrupa y resume valores de un data frame. Generalmente, se utiliza conjuntamente con group_by(), para agrupar antes los datos.

En el siguiente bloque de código, se utiliza summarise() para generar un nuevo data frame con los nuevos casos de COVID-19 sumarizados por mes.

# Selección, renombramiento, filtrado y conversión de columnas
covid_positivos_nuevos_sumarizado_x_mes <-
  covid %>%
  select(FECHA, nue_posi) %>%
  rename(fecha = FECHA, positivos_nuevos = nue_posi) %>%
  mutate(fecha = as.Date(fecha, format = "%d/%m/%Y")) %>%
  group_by(anio = format(fecha,"%Y"), mes = format(fecha,"%m")) %>%
  summarise(suma_positivos = sum(positivos_nuevos))

# Despliegue del data frame con los resultados
covid_positivos_nuevos_sumarizado_x_mes
# A tibble: 19 × 3
# Groups:   anio [2]
   anio  mes   suma_positivos
   <chr> <chr>          <int>
 1 2020  03               347
 2 2020  04               372
 3 2020  05               337
 4 2020  06              2403
 5 2020  07             14361
 6 2020  08             23467
 7 2020  09             34473
 8 2020  10             34211
 9 2020  11             29667
10 2020  12             29683
11 2021  01             24959
12 2021  02             10626
13 2021  03             12440
14 2021  04             33645
15 2021  05             67995
16 2021  06             48952
17 2021  07             40262
18 2021  08             55526
19 2021  09             33010

Corrections

If you see mistakes or want to suggest changes, please create an issue on the source repository.

Reuse

Text and figures are licensed under Creative Commons Attribution CC BY-SA 4.0. Source code is available at https://github.com/tpb728O-programaciongeoespacialr/2021ii/, unless otherwise noted. The figures that have been reused from other sources don't fall under this license and can be recognized by a note in their caption: "Figure from ...".