# Cálculo de la masa promedio para cada especie de pingüinos
# que habita en la isla Biscoe
|>
penguins filter(island == "Biscoe") |>
group_by(species) |>
summarize(
body_mass_g_mean = mean(body_mass_g, na.rm = TRUE)
)
10 dplyr - gramática para manipulación de datos
10.1 Resumen
El paquete dplyr proporciona un conjunto de funciones que ayudan a solucionar las tareas de transformación de datos más comunes, entre las que están la selección de columnas, el ordenamiento de filas, el filtrado de filas, la creación o modificación de columnas y los cálculos en grupos de filas. Estas transformaciones son usualmente requeridas antes de la visualización y el modelado de los datos.
10.2 Trabajo previo
10.2.1 Lecturas
Wickham, H., Çetinkaya-Rundel, M., & Grolemund, G. (s. f.). R for Data Science (2nd ed.) Chapter 4 - Data transformation. Recuperado 28 de abril de 2023, de https://r4ds.hadley.nz/data-transform.html
10.3 Introducción
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 procesamiento de datos más comunes. Los principales “verbos” (i.e. funciones) de esta gramática son:
select(): selecciona columnas con base en sus nombres.
filter(): selecciona filas con base en sus valores.
arrange(): cambia el orden de las filas.
mutate(): crea nuevas columnas, las cuales se expresan como funciones de columnas existentes.
summarize(): agrupa y resume valores.
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.
Las funciones de dplyr pueden encadenarse a través del operador pipe (tubo), ya sea el del paquete magrittr (%>%) o el del paquete base de R (|>). Los procesos se enlazan con pipes para formar pipelines (tuberías).
Todas las funciones de dplyr trabajan de manera similar:
- El primer argumento siempre es un data frame. Puede omitirse si la función recibe el data frame a través del operador pipe.
- Los argumentos siguientes describen que hacer con el data frame, utilizando los nombres de las columnas (sin comillas).
- El resultado siempre es un nuevo data frame.
Ya que cada función de dplyr se especializa en una sola tarea, usualmente es necesario encadenar funciones mediante pipes para lograr un objetivo de procesamiento de datos. Por ejemplo, el siguiente bloque de código usa tres verbos, o funciones, de dplyr para obtener la masa promedio de cada especie de pingüinos que habita en la isla Biscoe.
A tibble: 2 × 2
species body_mass_g_mean
<fct> <dbl>
Adelie 3710.659
Gentoo 5076.016
10.4 Instalación y carga
El paquete dplyr puede instalarse junto con todos los demás paquete de Tidyverse o de manera individual:
# Instalación conjunta de Tidyverse
install.packages("tidyverse")
# Instalación individual
install.packages("dplyr")
Una vez instalado, dplyr puede cargarse con la función library()
:
# Carga conjunta de Tidyverse
library(tidyverse)
# Carga individual
library(dplyr)
Seguidamente, se cargan algunos paquetes adicionales que se utilizan en este capítulo.
# Carga de readr, paquete para lectura de datos
library(readr)
# Carga de tidyr, paquete para creación de datos "tidy"
library(tidyr)
10.5 Conjuntos de datos para ejemplos
En los ejemplos de este capítulo, se utilizan dos conjunto de datos:
penguins
, contenido en el paquete palmerpenguins.- Estadísticas de delitos cometidos en 2022, disponibles en el sitio de datos abiertos del Organismo de Investigación Judicial (OIJ).
10.5.1 penguins
Para cargar el conjunto de datos penguins
, basta con cargar el paquete palmerpenguins
.
# Carga del paquete de datos palmerpenguins
library(palmerpenguins)
La función glimpse() despliega la estructura de un conjunto de datos, incluyendo los nombres de las columnas, sus tipos de datos y una muestra de estos:
# Estructura del conjunto de datos penguins
glimpse(penguins)
Rows: 344
Columns: 8
$ species <fct> Adelie, Adelie, Adelie, Adelie, Adelie, Adelie, Adel…
$ island <fct> Torgersen, Torgersen, Torgersen, Torgersen, Torgerse…
$ bill_length_mm <dbl> 39.1, 39.5, 40.3, NA, 36.7, 39.3, 38.9, 39.2, 34.1, …
$ bill_depth_mm <dbl> 18.7, 17.4, 18.0, NA, 19.3, 20.6, 17.8, 19.6, 18.1, …
$ flipper_length_mm <int> 181, 186, 195, NA, 193, 190, 181, 195, 193, 190, 186…
$ body_mass_g <int> 3750, 3800, 3250, NA, 3450, 3650, 3625, 4675, 3475, …
$ sex <fct> male, female, female, NA, female, male, female, male…
$ year <int> 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007…
Un conjunto de datos puede visualizarse al escribir su nombre en la consola de R o en un programa:
# Despliegue de los datos de penguins
penguins
# A tibble: 344 × 8
species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
<fct> <fct> <dbl> <dbl> <int> <int>
1 Adelie Torgersen 39.1 18.7 181 3750
2 Adelie Torgersen 39.5 17.4 186 3800
3 Adelie Torgersen 40.3 18 195 3250
4 Adelie Torgersen NA NA NA NA
5 Adelie Torgersen 36.7 19.3 193 3450
6 Adelie Torgersen 39.3 20.6 190 3650
7 Adelie Torgersen 38.9 17.8 181 3625
8 Adelie Torgersen 39.2 19.6 195 4675
9 Adelie Torgersen 34.1 18.1 193 3475
10 Adelie Torgersen 42 20.2 190 4250
# ℹ 334 more rows
# ℹ 2 more variables: sex <fct>, year <int>
penguins
es un tibble, un tipo especial de data frame que se utiliza en Tidyverse. La diferencia más importante entre un tibble y un data frame es la manera en la que se imprimen: los tibbles están diseñados para conjuntos de datos grandes, por lo que solo muestran los primeros registros y las columnas que caben en la pantalla. Un data frame regular muestra todas sus columnas y muchos más registros, lo que dificulta su visualización. En general, un data frame regular y un tibble pueden tratarse indistintamente.
10.5.2 Estadísticas de delitos cometidos en 2022
Se utiliza la función readr::read_csv() para leer un archivo CSV almacenado en el repositorio GitHub de este curso, con los datos de las estadísticas policiales proporcionados por el OIJ en formato Excel. readr::read_csv()
es más eficiente que read.csv()
(del paquete base de R) y tiene otras ventajas como detección automática de tipos de datos y mejor integración con otros paquetes de Tidyverse (ej. dplyr, tidyr, ggplot2).
# Carga de los datos de delitos cometidos en 2022
<-
delitos_2022 read.csv(
"https://raw.githubusercontent.com/gf0604-procesamientodatosgeograficos/2023-i/main/datos/oij/estadisticas-policiales/estadisticaspoliciales2022.csv"
)
Estructura del conjunto de datos:
# Estructura de los datos de delitos cometidos en 2022
glimpse(delitos_2022)
Rows: 96,651
Columns: 12
$ Delito <chr> "DELITOS CONTRA LA ADMINISTRACION DE JUSTICIA", "DELITOS …
$ SubDelito <chr> "FALSAS ACUSACIONES", "AMENAZA A UN FUNCIONARIO PUBLICO",…
$ Fecha <chr> "12/31/2022", "12/31/2022", "12/31/2022", "12/31/2022", "…
$ Hora <chr> "09:00:00 - 11:59:59", "12:00:00 - 14:59:59", "15:00:00 -…
$ Victima <chr> "VEHICULO", "PERSONA", "PERSONA", "PERSONA", "PERSONA", "…
$ SubVictima <chr> "SERVICIO PUBLICO/TAXI LEGAL O PIRATA/AUTOBUS", "OTRO O I…
$ Edad <chr> "Adulto Mayor", "Mayor de edad", "Mayor de edad", "Mayor …
$ Genero <chr> "Adulto Mayor", "Mayor de edad", "Mayor de edad", "Mayor …
$ Nacionalidad <chr> "COSTA RICA", "COSTA RICA", "COSTA RICA", "COSTA RICA", "…
$ Provincia <chr> "SAN JOSE", "SAN JOSE", "LIMON", "CARTAGO", "PUNTARENAS",…
$ Canton <chr> "SAN JOSE", "PEREZ ZELEDON", "SIQUIRRES", "CARTAGO", "QUE…
$ Distrito <chr> "HOSPITAL", "DANIEL FLORES", "SIQUIRRES", "GUADALUPE", "Q…
Despliegue de los datos (debido a que delitos_2022
es un data frame, pero no un tibble, se limitan las filas y columnas que se muestran):
# Despliegue de una muestra de los datos de delitos cometidos en 2022
1:10, c("Delito", "Victima", "Provincia")] delitos_2022[
Delito Victima Provincia
1 DELITOS CONTRA LA ADMINISTRACION DE JUSTICIA VEHICULO SAN JOSE
2 DELITOS CONTRA LA AUTORIDAD PUBLICA PERSONA SAN JOSE
3 DELITOS CONTRA LA LIBERTAD PERSONA LIMON
4 DELITOS CONTRA LA LIBERTAD PERSONA CARTAGO
5 DELITOS CONTRA LA LIBERTAD PERSONA PUNTARENAS
6 DELITOS CONTRA LA LIBERTAD PERSONA SAN JOSE
7 DELITOS CONTRA LA LIBERTAD PERSONA SAN JOSE
8 DELITOS CONTRA LA LIBERTAD PERSONA SAN JOSE
9 DELITOS CONTRA LA LIBERTAD PERSONA SAN JOSE
10 DELITOS CONTRA LA LIBERTAD PERSONA SAN JOSE
En RStudio, un conjunto de datos completo puede verse más cómodamente con la función View()
.
10.6 Funciones
En esta sección, se describen y ejemplifican las principales funciones de dplyr.
10.6.1 select()
La función select() selecciona (y opcionalmente renombra) columnas de un data frame con base en sus nombres.
# Selección de las columnas species, bill_length_mm y sex
|>
penguins select(species, bill_length_mm, sex)
# A tibble: 344 × 3
species bill_length_mm sex
<fct> <dbl> <fct>
1 Adelie 39.1 male
2 Adelie 39.5 female
3 Adelie 40.3 female
4 Adelie NA <NA>
5 Adelie 36.7 female
6 Adelie 39.3 male
7 Adelie 38.9 female
8 Adelie 39.2 male
9 Adelie 34.1 <NA>
10 Adelie 42 <NA>
# ℹ 334 more rows
Cambio de nombres de columnas:
# Selección y cambio de nombre de las columnas
# species, bill_length_mm y sex
|>
penguins select(especie = species,
longitud_pico_mm = bill_length_mm,
sexo = sex)
# A tibble: 344 × 3
especie longitud_pico_mm sexo
<fct> <dbl> <fct>
1 Adelie 39.1 male
2 Adelie 39.5 female
3 Adelie 40.3 female
4 Adelie NA <NA>
5 Adelie 36.7 female
6 Adelie 39.3 male
7 Adelie 38.9 female
8 Adelie 39.2 male
9 Adelie 34.1 <NA>
10 Adelie 42 <NA>
# ℹ 334 more rows
El operador :
permite seleccionar un rango de columnas continuas:
# Selección de las columnas desde species a flipper_length_mm
|>
penguins select(species:flipper_length_mm)
# A tibble: 344 × 5
species island bill_length_mm bill_depth_mm flipper_length_mm
<fct> <fct> <dbl> <dbl> <int>
1 Adelie Torgersen 39.1 18.7 181
2 Adelie Torgersen 39.5 17.4 186
3 Adelie Torgersen 40.3 18 195
4 Adelie Torgersen NA NA NA
5 Adelie Torgersen 36.7 19.3 193
6 Adelie Torgersen 39.3 20.6 190
7 Adelie Torgersen 38.9 17.8 181
8 Adelie Torgersen 39.2 19.6 195
9 Adelie Torgersen 34.1 18.1 193
10 Adelie Torgersen 42 20.2 190
# ℹ 334 more rows
Selección de todas las columnas que cumplen una condición:
# Selección de las columnas numéricas
|>
penguins select(where(is.numeric))
# A tibble: 344 × 5
bill_length_mm bill_depth_mm flipper_length_mm body_mass_g year
<dbl> <dbl> <int> <int> <int>
1 39.1 18.7 181 3750 2007
2 39.5 17.4 186 3800 2007
3 40.3 18 195 3250 2007
4 NA NA NA NA 2007
5 36.7 19.3 193 3450 2007
6 39.3 20.6 190 3650 2007
7 38.9 17.8 181 3625 2007
8 39.2 19.6 195 4675 2007
9 34.1 18.1 193 3475 2007
10 42 20.2 190 4250 2007
# ℹ 334 more rows
10.6.2 filter()
La función filter() retorna un subconjunto de un data frame con todas las filas que satisfacen una condición (i.e. expresión lógica).
Puede utilizar los operadores relacionales:
==
(igual que) Note la diferencia con el operador de asignación:=
!=
(diferente de)>
(estrictamente mayor que),>=
(mayor o igual que)<
(estrictamente menor que),<=
(menor o igual que)
Y los operadores lógicos:
&
(AND o Y lógico)|
(OR u O lógico)!
(NOT o NO lógico)
Ejemplos de uso de expresiones y operadores lógicos:
# Pingüinos de la especie 'Adelie'
# con longitud del pico mayor o igual a 45 mm
|>
penguins filter(species == 'Adelie' & bill_length_mm >= 45)
# A tibble: 3 × 8
species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
<fct> <fct> <dbl> <dbl> <int> <int>
1 Adelie Torgersen 46 21.5 194 4200
2 Adelie Torgersen 45.8 18.9 197 4150
3 Adelie Biscoe 45.6 20.3 191 4600
# ℹ 2 more variables: sex <fct>, year <int>
# Pingüinos de las especies 'Adelie' o 'Gentoo'
|>
penguins filter(species == 'Adelie' | species == 'Gentoo')
# A tibble: 276 × 8
species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
<fct> <fct> <dbl> <dbl> <int> <int>
1 Adelie Torgersen 39.1 18.7 181 3750
2 Adelie Torgersen 39.5 17.4 186 3800
3 Adelie Torgersen 40.3 18 195 3250
4 Adelie Torgersen NA NA NA NA
5 Adelie Torgersen 36.7 19.3 193 3450
6 Adelie Torgersen 39.3 20.6 190 3650
7 Adelie Torgersen 38.9 17.8 181 3625
8 Adelie Torgersen 39.2 19.6 195 4675
9 Adelie Torgersen 34.1 18.1 193 3475
10 Adelie Torgersen 42 20.2 190 4250
# ℹ 266 more rows
# ℹ 2 more variables: sex <fct>, year <int>
# Pingüinos de especies diferentes a 'Chinstrap'
|>
penguins filter(!(species == 'Chinstrap'))
# A tibble: 276 × 8
species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
<fct> <fct> <dbl> <dbl> <int> <int>
1 Adelie Torgersen 39.1 18.7 181 3750
2 Adelie Torgersen 39.5 17.4 186 3800
3 Adelie Torgersen 40.3 18 195 3250
4 Adelie Torgersen NA NA NA NA
5 Adelie Torgersen 36.7 19.3 193 3450
6 Adelie Torgersen 39.3 20.6 190 3650
7 Adelie Torgersen 38.9 17.8 181 3625
8 Adelie Torgersen 39.2 19.6 195 4675
9 Adelie Torgersen 34.1 18.1 193 3475
10 Adelie Torgersen 42 20.2 190 4250
# ℹ 266 more rows
# ℹ 2 more variables: sex <fct>, year <int>
# Homicidios cometidos en el cantón de Esparza
|>
delitos_2022 filter(SubDelito == "HOMICIDIO" & Canton == "ESPARZA") |>
select(SubDelito, Canton, Fecha, Victima, Edad, Nacionalidad)
SubDelito Canton Fecha Victima Edad Nacionalidad
1 HOMICIDIO ESPARZA 12/24/2022 PERSONA Mayor de edad COSTA RICA
2 HOMICIDIO ESPARZA 06/13/2022 PERSONA Mayor de edad COSTA RICA
3 HOMICIDIO ESPARZA 05/13/2022 PERSONA Desconocido Desconocido
4 HOMICIDIO ESPARZA 04/08/2022 PERSONA Mayor de edad COLOMBIA
5 HOMICIDIO ESPARZA 03/20/2022 PERSONA Mayor de edad COSTA RICA
6 HOMICIDIO ESPARZA 01/06/2022 PERSONA Menor de edad COSTA RICA
# Homicidios cometidos en el cantón de Esparza
# a personas no costarricenses
|>
delitos_2022 filter(SubDelito == "HOMICIDIO" &
== "ESPARZA" & Nacionalidad != "COSTA RICA") |>
Canton select(SubDelito, Canton, Fecha, Victima, Edad, Nacionalidad)
SubDelito Canton Fecha Victima Edad Nacionalidad
1 HOMICIDIO ESPARZA 05/13/2022 PERSONA Desconocido Desconocido
2 HOMICIDIO ESPARZA 04/08/2022 PERSONA Mayor de edad COLOMBIA
# Pingüinos con longitud del pico mayor o igual al promedio
# El argumento lógico na.rm de mean()
# indica si los valores NA ("not available")
# deben ser removidos antes del cálculo
|>
penguins filter(bill_length_mm >= mean(bill_length_mm, na.rm = TRUE))
# A tibble: 175 × 8
species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
<fct> <fct> <dbl> <dbl> <int> <int>
1 Adelie Torgersen 46 21.5 194 4200
2 Adelie Dream 44.1 19.7 196 4400
3 Adelie Torgersen 45.8 18.9 197 4150
4 Adelie Biscoe 45.6 20.3 191 4600
5 Adelie Torgersen 44.1 18 210 4000
6 Gentoo Biscoe 46.1 13.2 211 4500
7 Gentoo Biscoe 50 16.3 230 5700
8 Gentoo Biscoe 48.7 14.1 210 4450
9 Gentoo Biscoe 50 15.2 218 5700
10 Gentoo Biscoe 47.6 14.5 215 5400
# ℹ 165 more rows
# ℹ 2 more variables: sex <fct>, year <int>
Condiciones relacionadas con valores NA
(nulos):
# Filas con valor NA en la columna sex
|>
penguins select(species, island, sex) |>
filter(is.na(sex))
# A tibble: 11 × 3
species island sex
<fct> <fct> <fct>
1 Adelie Torgersen <NA>
2 Adelie Torgersen <NA>
3 Adelie Torgersen <NA>
4 Adelie Torgersen <NA>
5 Adelie Torgersen <NA>
6 Adelie Dream <NA>
7 Gentoo Biscoe <NA>
8 Gentoo Biscoe <NA>
9 Gentoo Biscoe <NA>
10 Gentoo Biscoe <NA>
11 Gentoo Biscoe <NA>
La función tidyr::drop_na() remueve las filas con valores NA
en una o varias columnas.
# Filas con valor diferente a NA en la columna sex
|>
penguins select(species,
bill_length_mm,
bill_depth_mm,
flipper_length_mm,
body_mass_g,|>
sex) drop_na(sex)
# A tibble: 333 × 6
species bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex
<fct> <dbl> <dbl> <int> <int> <fct>
1 Adelie 39.1 18.7 181 3750 male
2 Adelie 39.5 17.4 186 3800 female
3 Adelie 40.3 18 195 3250 female
4 Adelie 36.7 19.3 193 3450 female
5 Adelie 39.3 20.6 190 3650 male
6 Adelie 38.9 17.8 181 3625 female
7 Adelie 39.2 19.6 195 4675 male
8 Adelie 41.1 17.6 182 3200 female
9 Adelie 38.6 21.2 191 3800 male
10 Adelie 34.6 21.1 198 4400 male
# ℹ 323 more rows
# Filas con valor diferente a NA en cualquier columna
|>
penguins select(species,
bill_length_mm,
bill_depth_mm,
flipper_length_mm,
body_mass_g,|>
sex) drop_na()
# A tibble: 333 × 6
species bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex
<fct> <dbl> <dbl> <int> <int> <fct>
1 Adelie 39.1 18.7 181 3750 male
2 Adelie 39.5 17.4 186 3800 female
3 Adelie 40.3 18 195 3250 female
4 Adelie 36.7 19.3 193 3450 female
5 Adelie 39.3 20.6 190 3650 male
6 Adelie 38.9 17.8 181 3625 female
7 Adelie 39.2 19.6 195 4675 male
8 Adelie 41.1 17.6 182 3200 female
9 Adelie 38.6 21.2 191 3800 male
10 Adelie 34.6 21.1 198 4400 male
# ℹ 323 more rows
10.6.3 arrange()
La función arrange() cambia el orden de las filas de un data frame de acuerdo con los valores de las columnas seleccionadas.
# Ordenamiento ascendente por las columnas
# bill_length_mm y bill_depth_mm
|>
penguins arrange(bill_length_mm, bill_depth_mm)
# A tibble: 344 × 8
species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
<fct> <fct> <dbl> <dbl> <int> <int>
1 Adelie Dream 32.1 15.5 188 3050
2 Adelie Dream 33.1 16.1 178 2900
3 Adelie Torgersen 33.5 19 190 3600
4 Adelie Dream 34 17.1 185 3400
5 Adelie Torgersen 34.1 18.1 193 3475
6 Adelie Torgersen 34.4 18.4 184 3325
7 Adelie Biscoe 34.5 18.1 187 2900
8 Adelie Torgersen 34.6 17.2 189 3200
9 Adelie Torgersen 34.6 21.1 198 4400
10 Adelie Biscoe 35 17.9 190 3450
# ℹ 334 more rows
# ℹ 2 more variables: sex <fct>, year <int>
Por defecto, las columnas se ordenan de manera acendente. Si se desea un orden descendente, puede utilizarse la función desc().
# Ordenamiento descendente por las columnas
# bill_length_mm y bill_depth_mm
|>
penguins arrange(desc(bill_length_mm), desc(bill_depth_mm))
# A tibble: 344 × 8
species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
<fct> <fct> <dbl> <dbl> <int> <int>
1 Gentoo Biscoe 59.6 17 230 6050
2 Chinstrap Dream 58 17.8 181 3700
3 Gentoo Biscoe 55.9 17 228 5600
4 Chinstrap Dream 55.8 19.8 207 4000
5 Gentoo Biscoe 55.1 16 230 5850
6 Gentoo Biscoe 54.3 15.7 231 5650
7 Chinstrap Dream 54.2 20.8 201 4300
8 Chinstrap Dream 53.5 19.9 205 4500
9 Gentoo Biscoe 53.4 15.8 219 5500
10 Chinstrap Dream 52.8 20 205 4550
# ℹ 334 more rows
# ℹ 2 more variables: sex <fct>, year <int>
Nótese que los valores NA
se ubican al final de cualquier ordenamiento.
10.6.4 mutate()
La función mutate() crea o modifica columnas en un data frame.
# Creación de la columna body_mass_kg,
# correspondiente al valor de body_mass_g, pero expresado en kg
|>
penguins select(species, body_mass_g) |>
mutate(body_mass_kg = body_mass_g/1000)
# A tibble: 344 × 3
species body_mass_g body_mass_kg
<fct> <int> <dbl>
1 Adelie 3750 3.75
2 Adelie 3800 3.8
3 Adelie 3250 3.25
4 Adelie NA NA
5 Adelie 3450 3.45
6 Adelie 3650 3.65
7 Adelie 3625 3.62
8 Adelie 4675 4.68
9 Adelie 3475 3.48
10 Adelie 4250 4.25
# ℹ 334 more rows
# Creación de las columnas body_mass_g_mean (promedio de masa) y
# body_mass_g_normalized (masa normalizada con respecto al promedio)
|>
penguins select(species, body_mass_g) |>
mutate(body_mass_g_mean = mean(body_mass_g, na.rm = TRUE)) |>
mutate(body_mass_g_normalized = body_mass_g / body_mass_g_mean)
# A tibble: 344 × 4
species body_mass_g body_mass_g_mean body_mass_g_normalized
<fct> <int> <dbl> <dbl>
1 Adelie 3750 4202. 0.892
2 Adelie 3800 4202. 0.904
3 Adelie 3250 4202. 0.773
4 Adelie NA 4202. NA
5 Adelie 3450 4202. 0.821
6 Adelie 3650 4202. 0.869
7 Adelie 3625 4202. 0.863
8 Adelie 4675 4202. 1.11
9 Adelie 3475 4202. 0.827
10 Adelie 4250 4202. 1.01
# ℹ 334 more rows
# Creación de las columnas
# Fecha_Date (tipo Date), Anio, Mes y Dia (enteros)
|>
delitos_2022 select(Fecha) |>
mutate(Fecha_Date = as.Date(delitos_2022$Fecha, format="%m/%d/%Y")) |>
mutate(Anio = as.integer(format(as.Date(delitos_2022$Fecha, format="%m/%d/%Y"), "%Y"))) |>
mutate(Dia = as.integer(format(as.Date(delitos_2022$Fecha, format="%m/%d/%Y"), "%m"))) |>
mutate(Mes = as.integer(format(as.Date(delitos_2022$Fecha, format="%m/%d/%Y"), "%d"))) |>
slice_head(n = 10)
Fecha Fecha_Date Anio Dia Mes
1 12/31/2022 2022-12-31 2022 12 31
2 12/31/2022 2022-12-31 2022 12 31
3 12/31/2022 2022-12-31 2022 12 31
4 12/31/2022 2022-12-31 2022 12 31
5 12/31/2022 2022-12-31 2022 12 31
6 12/31/2022 2022-12-31 2022 12 31
7 12/31/2022 2022-12-31 2022 12 31
8 12/31/2022 2022-12-31 2022 12 31
9 12/31/2022 2022-12-31 2022 12 31
10 12/31/2022 2022-12-31 2022 12 31
La función group_by() agrupa una o más columnas. Generalmente, esto se hace con el objetivo de rea
# Creación de la columnas
# body_mass_g_mean_species (promedio de masa de la especie) y
# body_mass_g_species_normalized (masa normalizada con respecto al promedio de la especie)
|>
penguins select(species, body_mass_g) |>
group_by(species) |>
mutate(body_mass_g_mean_species = mean(body_mass_g, na.rm = TRUE)) |>
mutate(body_mass_g_species_normalized = body_mass_g / body_mass_g_mean_species)
# A tibble: 344 × 4
# Groups: species [3]
species body_mass_g body_mass_g_mean_species body_mass_g_species_normalized
<fct> <int> <dbl> <dbl>
1 Adelie 3750 3701. 1.01
2 Adelie 3800 3701. 1.03
3 Adelie 3250 3701. 0.878
4 Adelie NA 3701. NA
5 Adelie 3450 3701. 0.932
6 Adelie 3650 3701. 0.986
7 Adelie 3625 3701. 0.980
8 Adelie 4675 3701. 1.26
9 Adelie 3475 3701. 0.939
10 Adelie 4250 3701. 1.15
# ℹ 334 more rows
10.6.5 summarize()
La función summarize() se utiliza generalmente junto con la función group_by() para realizar cálculos en grupos de filas de un data frame. group_by()
agrupa las filas y summarize()
realiza los cálculos (ej. sumas, promedios) en las columnas, para cada grupo. El resultado es un nuevo data frame con una fila por grupo. Si no hay agrupación, se retorna una sola fila correspondiente a los cálculos para todo el data frame.
Ejemplos de cálculos en grupos:
# Creación de un data frame con las columnas calculadas de
# mínimo, máximo y promedio de masa,
# y cantidad de individuos para cada especie
|>
penguins group_by(species) |>
summarize(
body_mass_g_min = min(body_mass_g, na.rm = TRUE),
body_mass_g_max = max(body_mass_g, na.rm = TRUE),
body_mass_g_mean = mean(body_mass_g, na.rm = TRUE),
n = n()
)
# A tibble: 3 × 5
species body_mass_g_min body_mass_g_max body_mass_g_mean n
<fct> <int> <int> <dbl> <int>
1 Adelie 2850 4775 3701. 152
2 Chinstrap 2700 4800 3733. 68
3 Gentoo 3950 6300 5076. 124
La función n() cuenta la cantidad de filas en un grupo.
# Creación de un data frame con la cantidad de homicidios
# por provincia, cantón
|>
delitos_2022 filter(SubDelito == "HOMICIDIO") |>
group_by(Provincia, Canton) |>
summarize(
homicidios_2022 = n()
|>
) arrange(desc(homicidios_2022)) |>
print(n = Inf)
# A tibble: 68 × 3
# Groups: Provincia [7]
Provincia Canton homicidios_2022
<chr> <chr> <int>
1 SAN JOSE SAN JOSE 48
2 LIMON LIMON 47
3 PUNTARENAS PUNTARENAS 43
4 ALAJUELA ALAJUELA 42
5 LIMON POCOCI 38
6 LIMON MATINA 25
7 LIMON GUACIMO 17
8 ALAJUELA SAN CARLOS 16
9 ALAJUELA SAN RAMON 15
10 CARTAGO CARTAGO 15
11 SAN JOSE GOICOECHEA 15
12 HEREDIA SARAPIQUI 14
13 PUNTARENAS CORREDORES 14
14 CARTAGO LA UNION 12
15 HEREDIA HEREDIA 12
16 PUNTARENAS GARABITO 11
17 GUANACASTE LIBERIA 10
18 GUANACASTE SANTA CRUZ 10
19 LIMON SIQUIRRES 9
20 GUANACASTE NICOYA 8
21 LIMON TALAMANCA 8
22 SAN JOSE ASERRI 8
23 HEREDIA SANTO DOMINGO 7
24 PUNTARENAS BUENOS AIRES 7
25 SAN JOSE DESAMPARADOS 7
26 SAN JOSE TIBAS 7
27 GUANACASTE CARRILLO 6
28 GUANACASTE LA CRUZ 6
29 PUNTARENAS ESPARZA 6
30 SAN JOSE ALAJUELITA 6
31 ALAJUELA GRECIA 5
32 GUANACASTE BAGACES 5
33 GUANACASTE CANAS 5
34 PUNTARENAS GOLFITO 5
35 PUNTARENAS OSA 5
36 PUNTARENAS PARRITA 5
37 PUNTARENAS QUEPOS 5
38 SAN JOSE PEREZ ZELEDON 5
39 ALAJUELA LOS CHILES 4
40 ALAJUELA POAS 4
41 CARTAGO TURRIALBA 4
42 HEREDIA BARVA 4
43 HEREDIA SAN RAFAEL 4
44 PUNTARENAS COTO BRUS 4
45 PUNTARENAS MONTES DE ORO 4
46 ALAJUELA ATENAS 3
47 ALAJUELA NARANJO 3
48 ALAJUELA RIO CUARTO 3
49 CARTAGO EL GUARCO 3
50 CARTAGO OREAMUNO 3
51 CARTAGO PARAISO 3
52 GUANACASTE TILARAN 3
53 SAN JOSE ESCAZU 3
54 SAN JOSE MORAVIA 3
55 ALAJUELA OROTINA 2
56 ALAJUELA SARCHÍ 2
57 ALAJUELA UPALA 2
58 SAN JOSE CURRIDABAT 2
59 SAN JOSE SANTA ANA 2
60 SAN JOSE TURRUBARES 2
61 ALAJUELA PALMARES 1
62 ALAJUELA ZARCERO 1
63 CARTAGO JIMENEZ 1
64 HEREDIA FLORES 1
65 HEREDIA SAN ISIDRO 1
66 HEREDIA SANTA BARBARA 1
67 SAN JOSE MONTES DE OCA 1
68 SAN JOSE PURISCAL 1
La función print() se utiliza para especificar la cantidad de filas que se imprimirán (Inf
quiere decir que se imprimirán todas).
# Creación de un data frame con la cantidad de registros
# por delito y subdelito
|>
delitos_2022 group_by(Delito, SubDelito) |>
summarize(
n = n()
|>
) arrange(desc(n)) |>
print(n = Inf)
# A tibble: 112 × 3
# Groups: Delito [27]
Delito SubDelito n
<chr> <chr> <int>
1 DELITOS CONTRA LA PROPIEDAD HURTO 15744
2 DELITOS CONTRA LA PROPIEDAD ROBO 14228
3 DELITOS CONTRA LA PROPIEDAD ASALTO 10794
4 ESTAFAS Y OTRAS DEFRAUDACIONES TIMOS 10430
5 ESTAFAS Y OTRAS DEFRAUDACIONES ESTAFA 6746
6 DELITOS CONTRA LA PROPIEDAD ROBO DE … 4225
7 DELITOS CONTRA LA LIBERTAD DELITOS … 4081
8 DELITOS CONTRA LA VIDA AGRESION 3424
9 DELITOS INFORMATICOS ESTAFA I… 3002
10 OTROS DELITOS OTRO O I… 2745
11 OTROS DELITOS CONTRA LA PROPIEDAD DAÑOS 2559
12 DELITOS CONTRA LA VIDA LESIONES 2218
13 OTROS DELITOS CONTRA LA PROPIEDAD ADMINIST… 1336
14 DELITOS SEXUALES VIOLACIO… 1285
15 OTROS DELITOS CONTRA LA PROPIEDAD EXTORSIO… 1249
16 DELITOS CONTRA LOS DEBERES DE LA FUNCION PUBLICA ABUSO DE… 1234
17 ESTAFAS Y OTRAS DEFRAUDACIONES FRAUDE 1084
18 DELITOS CONTRA LA PROPIEDAD ROBO DE … 863
19 DELITOS INFORMATICOS SUPLANTA… 771
20 DELITOS CONTRA LA VIDA HOMICIDI… 654
21 DELITOS CONTRA LA VIDA HOMICIDIO 604
22 DELITOS CONTRA LA ADMINISTRACION DE JUSTICIA ENCUBRIM… 526
23 DELITOS CONTRA LA VIDA MUERTE I… 522
24 NO DELITO DESAPARI… 476
25 INFRACCION A LA LEY DE PSICOTROPICOS TRAFICO … 434
26 DELITOS CONTRA LA SEGURIDAD COMUN INCENDIO… 410
27 DELITOS SEXUALES CORRUPCI… 378
28 NO DELITO DESAPARI… 376
29 DELITOS CONTRA LA FAMILIA VIOLENCI… 279
30 DELITOS INFORMATICOS SUPLANTA… 276
31 OTROS DELITOS CONTRA LA PROPIEDAD USURPACI… 272
32 LEY CONTRA EL ACOSO SEXUAL CALLEJERO LEY CONT… 240
33 DELITOS CONTRA LA SEGURIDAD COMUN DELITOS … 238
34 INFRACCION A LA LEY DE BIENESTAR ANIMAL MUERTE D… 209
35 DELITOS INFORMATICOS OTRO O I… 206
36 DELITOS INFORMATICOS DIFUSION… 205
37 DELITOS CONTRA LA VIDA SUICIDIO 174
38 DELITOS CONTRA LA VIDA MUERTE A… 163
39 DELITOS INFORMATICOS FACILITA… 155
40 DELITOS CONTRA LA FAMILIA SUSTRACC… 152
41 DELITOS CONTRA LA LIBERTAD DELITOS … 140
42 DELITOS CONTRA EL AMBITO DE LA INTIMIDAD VIOLACIO… 136
43 DELITOS INFORMATICOS ESPIONAJ… 127
44 DELITOS CONTRA LA VIDA ABANDONO… 116
45 INFRACCION A LA LEY DE BIENESTAR ANIMAL MALTRATO… 98
46 DELITOS CONTRA EL HONOR INJURIA,… 87
47 DELITOS CONTRA LA VIDA MUERTE N… 84
48 DELITOS INFORMATICOS SEDUCCIO… 80
49 DELITOS AMBIENTALES LEY FORE… 74
50 DELITOS CONTRA LA FAMILIA INCUMPLI… 73
51 INFRACCION A LA LEY DE PSICOTROPICOS LEGITIMA… 56
52 DELITOS CONTRA LA AUTORIDAD PUBLICA DESOBEDI… 54
53 INFRACCION A LA LEY DE BIENESTAR ANIMAL CRUELDAD… 50
54 DELITOS CONTRA LOS DEBERES DE LA FUNCION PUBLICA CORRUPCI… 46
55 DELITOS CONTRA EL AMBITO DE LA INTIMIDAD VIOLACIO… 45
56 DELITOS INFORMATICOS INSTALAC… 43
57 DELITOS AMBIENTALES LEY DE C… 33
58 DELITOS CONTRA LA ADMINISTRACION DE JUSTICIA FALSAS A… 30
59 ESTAFAS Y OTRAS DEFRAUDACIONES ADMINIST… 28
60 DELITOS INFORMATICOS SABOTAJE… 22
61 DELITOS SEXUALES OTRO O I… 19
62 DELITOS CONTRA LOS DEBERES DE LA FUNCION PUBLICA PECULADO… 17
63 DELITOS INFORMATICOS DAÑO INF… 15
64 ESTAFAS Y OTRAS DEFRAUDACIONES OTRO O I… 14
65 DELITOS CONTRA LA AUTORIDAD PUBLICA RESISTEN… 13
66 DELITOS CONTRA LA AUTORIDAD PUBLICA AMENAZA … 12
67 DELITOS CONTRA LOS DEBERES DE LA FUNCION PUBLICA CONCUSIO… 12
68 DELITOS AMBIENTALES USURPACI… 10
69 DELITOS CONTRA LA FE PUBLICA OTRO O I… 10
70 DELITOS CONTRA LA SEGURIDAD COMUN DELITOS … 10
71 INFRACCION A LA LEY DE PSICOTROPICOS TRAFICO … 9
72 DELITOS CONTRA LA FAMILIA PROTECCI… 8
73 DELITOS CONTRA LA SEGURIDAD COMUN DELITOS … 8
74 DELITOS CONTRA LA VIDA ABORTO 8
75 NO DELITO OTRO IND… 8
76 DELITOS CONTRA EL AMBITO DE LA INTIMIDAD INFRACCI… 7
77 OTROS DELITOS INFRACCI… 7
78 DELITOS AMBIENTALES LEY DE G… 6
79 INFRACCION A LA LEY DE BIENESTAR ANIMAL PELEA EN… 5
80 TRATA DE PERSONAS TRATA SE… 5
81 DELITOS CONTRA LA AUTORIDAD PUBLICA EJERCICI… 4
82 DELITOS CONTRA LA VIDA OTRO O I… 4
83 DELITOS AMBIENTALES LEY DE L… 3
84 DELITOS CONTRA EL AMBITO DE LA INTIMIDAD OTRO O I… 3
85 DELITOS CONTRA EL AMBITO DE LA INTIMIDAD TURBACIO… 3
86 DELITOS CONTRA LA AUTORIDAD PUBLICA USO ILEG… 3
87 DELITOS CONTRA LA TRANQUILIDAD PUBLICA INTIMIDA… 3
88 OTROS DELITOS CONTRA LA PROPIEDAD INFRACCI… 3
89 DELITOS AMBIENTALES LEY DE P… 2
90 DELITOS CONTRA LA ADMINISTRACION DE JUSTICIA EVASION … 2
91 DELITOS CONTRA LA BUENA FE DELOS NEGOCIOS USURA Y … 2
92 DELITOS CONTRA LOS DEBERES DE LA FUNCION PUBLICA PREVARIC… 2
93 DESCONOCIDO DESCONOC… 2
94 INFRACCION A LA LEY DE PSICOTROPICOS OTRO O I… 2
95 OTROS DELITOS CONTRA LA PROPIEDAD OTRO O I… 2
96 TRAFICO DE PERSONAS PERSONAS… 2
97 TRATA DE PERSONAS OTRO O I… 2
98 DELITOS CONTRA LA ADMINISTRACION DE JUSTICIA FALSO TE… 1
99 DELITOS CONTRA LA AUTORIDAD PUBLICA FACILITA… 1
100 DELITOS CONTRA LA AUTORIDAD PUBLICA VIOLACIO… 1
101 DELITOS CONTRA LA AUTORIDAD PUBLICA VIOLACIO… 1
102 DELITOS CONTRA LA BUENA FE DELOS NEGOCIOS DELITOS … 1
103 DELITOS CONTRA LA FAMILIA MATRIMON… 1
104 DELITOS CONTRA LA FAMILIA OTRO O I… 1
105 DELITOS CONTRA LA FE PUBLICA FALSEDAD… 1
106 DELITOS CONTRA LA LIBERTAD OTRO O I… 1
107 DELITOS CONTRA LOS PODERES PUBLICOS Y EL ORDEN CONSTITUCION… ATENTADO… 1
108 DELITOS CONTRA LOS PODERES PUBLICOS Y EL ORDEN CONSTITUCION… OTRO 1
109 DELITOS INFORMATICOS NARCOTRF… 1
110 DELITOS SEXUALES RAPTO 1
111 TRATA DE PERSONAS MENDICID… 1
112 TRATA DE PERSONAS TRATA LA… 1
Ejemplo de cálculos sin agrupamiento:
# Creación de un data frame con las columnas
# body_mass_g_mean (promedio de masa) y n (cantidad de registros)
|>
penguins summarise(body_mass_g_mean = mean(body_mass_g, na.rm = TRUE),
n = n())
# A tibble: 1 × 2
body_mass_g_mean n
<dbl> <int>
1 4202. 344
10.6.6 Otras
10.6.6.1 distinct()
La función distinct() retorna las combinaciones únicas de filas en un data frame.
# Valores distintos de la columna Victima
|>
delitos_2022 distinct(Victima)
Victima
1 VEHICULO
2 PERSONA
3 OTROS
4 VIVIENDA
5 EDIFICACION
10.6.6.2 count()
Una forma alternativa a summarize()
para realizar un conteo es con la función count():
# Conteo de delitos por tipo de Victima
|>
delitos_2022 count(Victima)
Victima n
1 EDIFICACION 6705
2 OTROS 4756
3 PERSONA 62046
4 VEHICULO 11752
5 VIVIENDA 11392
# Expresión equivalente con summarize
|>
delitos_2022 group_by(Victima) |>
summarize(n = n())
# A tibble: 5 × 2
Victima n
<chr> <int>
1 EDIFICACION 6705
2 OTROS 4756
3 PERSONA 62046
4 VEHICULO 11752
5 VIVIENDA 11392
10.7 Ejercicios
Utilice las funciones de dplyr para responder a las siguientes preguntas sobre el conjunto de datos penguins
:
- ¿Cuántos individuos de cada sexo hay en cada especie?
- ¿Cuál es el mínimo, máximo y promedio de masa corporal (peso) por especie y sexo?
- ¿Cuántos individuos se observaron durante cada año?
- ¿Cuántos individuos de cada especie se observaron durante cada año?
- ¿Cuántos individuos de cada especie y cada sexo se observaron durante cada año?
- ¿Cuál es el promedio de masa corporal (peso) por año?
- ¿Cuál es el promedio de masa corporal (peso) por año para cada especie?
10.8 Recursos de interés
RStudio. (2017). Data transformation with dplyr::Cheat Sheet. https://github.com/rstudio/cheatsheets/blob/45c1e642468695830fd8b724587ccfe8901e2185/data-transformation.pdf