Menu

dplyr en R: filter, select, mutate, summarize — Introducción práctica

Qué es dplyr, cómo instalarlo y cómo sus seis verbos principales más el pipe convierten código enredado de data frames en pipelines legibles.

Esta página incluye editores ejecutables: edita, ejecuta y ve el resultado al instante.

Qué es dplyr

dplyr es el paquete más popular de R para manipulación de datos: una "gramática de datos" construida a partir de un puñado de verbos. Cada verbo es una función que recibe un data frame, hace exactamente un trabajo (conservar algunas filas, añadir una columna, calcular un resumen por grupo) y devuelve un nuevo data frame. Como todos los verbos tienen la misma forma - entra un data frame, sale un data frame - encajan entre sí con el pipe formando pipelines que se leen de arriba abajo como una receta. dplyr es el núcleo del tidyverse, una familia de paquetes (tidyr, ggplot2, readr) que comparten este diseño.

Todo lo que hace dplyr, R base también lo hace. Aquí tienes un pequeño análisis en R base puro: filtrar los datos integrados mtcars a los coches de 6 cilindros, calcular una columna nueva y promediarla por número de marchas. Este sí se ejecuta:

Funciona, y es buen R. Pero fíjate en cómo la historia queda repartida entre indexación con corchetes, una asignación con $ y una fórmula. La versión dplyr del mismo análisis:

library(dplyr)

mtcars |>
    filter(cyl == 4) |>
    mutate(kml = mpg * 0.425) |>
    group_by(gear) |>
    summarize(avg_kml = round(mean(kml), 1))

Cuatro verbos, en el orden en que los explicarías en voz alta. Esa legibilidad es todo el argumento de venta, y en un pipeline de veinte pasos resulta decisiva.

Los fragmentos de dplyr en esta página son estáticos porque este editor solo ejecuta R base; para ejecutarlos, instala dplyr en tu propia máquina como se muestra a continuación.

Instalar y cargar

Instalación única, y luego cárgalo en cada script que lo use:

install.packages("dplyr")   # once, per machine
library(dplyr)              # every script

Instalar install.packages("tidyverse") en su lugar trae dplyr junto con sus hermanos. Cuando dplyr se carga, avisa de que enmascara stats::filter y stats::lag - eso es normal, no un error.

Los seis verbos principales

Todos los verbos reciben el data frame como primer argumento y los nombres de columna a secas, sin comillas ni prefijos df$.

filter() conserva las filas que cumplen una condición:

mtcars |> filter(mpg > 25)
mtcars |> filter(cyl == 4, hp < 70)   # comma = AND

select() conserva columnas por nombre, rango o función auxiliar:

mtcars |> select(mpg, cyl, hp)
mtcars |> select(mpg:hp)              # a range of adjacent columns
mtcars |> select(starts_with("d"))    # disp, drat

mutate() añade o transforma columnas:

mtcars |> mutate(kml = mpg * 0.425, heavy = wt > 3.5)

arrange() ordena las filas - envuelve una columna en desc() para orden descendente:

mtcars |> arrange(desc(mpg))

summarize() colapsa las filas en una sola fila de resumen, y group_by() hace que colapse por grupo en su lugar:

mtcars |>
    group_by(cyl) |>
    summarize(n = n(), avg_mpg = mean(mpg))

group_by() no hace nada visible por sí solo: simplemente etiqueta el data frame para que el siguiente summarize() (o mutate()) trabaje grupo a grupo. Cada verbo tiene su documentación completa en este capítulo: filtrar filas, añadir columnas, ordenar y resúmenes por grupo.

Encadenar verbos con el pipe

El pipe |> toma el valor que lo precede y lo pasa como primer argumento de la función que lo sigue: x |> f(y) significa f(x, y). Como todo verbo de dplyr recibe y devuelve un data frame, los verbos se encadenan indefinidamente:

mtcars |>
    filter(hp > 100) |>
    mutate(kml = mpg * 0.425) |>
    group_by(cyl) |>
    summarize(cars = n(), avg_kml = round(mean(kml), 1)) |>
    arrange(desc(avg_kml))

Léelo en voz alta: toma mtcars, quédate con los coches de más de 100 caballos, añade una columna de km por litro, agrupa por cilindros, cuenta y promedia cada grupo, ordena por el promedio. Sin variables intermedias, sin anidamiento. El código más antiguo usa %>% del paquete magrittr en lugar de |> - para trabajar con dplyr son intercambiables, y |> (integrado en R 4.1+) se cubre en la documentación de pipes.

count() y n(): los ayudantes para contar

Contar es tan común que dplyr tiene atajos. n() da el número de filas del grupo actual (solo es válido dentro de summarize() o mutate()), y count() condensa todo el baile de group_by() + summarize(n = n()) en una sola llamada:

mtcars |> count(cyl)                    # rows per cyl value
mtcars |> count(cyl, gear, sort = TRUE) # two groupers, biggest first

Si te descubres escribiendo group_by(x) |> summarize(n = n()), sustitúyelo por count(x).

Una nota sobre tibbles

Los verbos de dplyr suelen devolver un tibble, la variante de data frame del tidyverse. Es un data frame (todo lo que acepta uno acepta un tibble), con una impresión más amigable: solo las primeras 10 filas, solo las columnas que caben, con los tipos mostrados bajo cada nombre. Dos diferencias que vale la pena conocer: los tibbles nunca usan nombres de fila (por eso mtcars |> as_tibble() pierde los nombres de los coches - el tidyverse espera que los identificadores vivan en una columna de verdad), y la indexación con corchete simple siempre devuelve un tibble en vez de degradarse a veces a un vector. Ninguna de las dos debería sorprenderte en el día a día; simplemente no te asustes cuando str() diga tbl_df.

Lo que te llevas

  • dplyr es una gramática: seis verbos, cada uno haciendo un trabajo sobre un data frame, encadenados con el pipe.
  • filter() elige filas, select() elige columnas, mutate() añade columnas, arrange() ordena, group_by() + summarize() agrega.
  • x |> f(y) es f(x, y) - los pipelines se leen de arriba abajo en el orden en que ocurren las cosas.
  • count() y n() cubren la mayoría de las necesidades de conteo.
  • R base puede hacer todo esto; dplyr gana en legibilidad cuando los pipelines crecen.

A continuación: filtrado y subconjuntos en profundidad - los idiomas de corchetes de R base y dónde encaja el filter() de dplyr.

Preguntas frecuentes

¿Qué es dplyr en R?

dplyr es el paquete de R más utilizado para manipular data frames. Te da un pequeño conjunto de verbos - filter(), select(), mutate(), arrange(), summarize(), group_by() - que hacen una sola cosa cada uno sobre un data frame y se encadenan con el pipe en pipelines legibles. Forma parte del tidyverse.

¿Cómo instalo dplyr?

Ejecuta install.packages("dplyr") una sola vez, y luego library(dplyr) al inicio de cada script que lo use. Si instalas tidyverse en su lugar, obtienes dplyr más sus paquetes hermanos (tidyr, ggplot2, readr) de una sola vez.

¿Necesito dplyr, o basta con R base?

R base puede hacer todo lo que hace dplyr - subconjuntos, aggregate(), order() - y vale la pena conocerlo porque funciona en cualquier parte sin dependencias. dplyr se gana su instalación cuando los pipelines se alargan: cinco verbos encadenados se leen como una frase, mientras que el equivalente en base se lee como un rompecabezas de corchetes anidados.

¿Cuál es la diferencia entre summarize y summarise en dplyr?

Ninguna. Son la misma función con las grafías estadounidense y británica; dplyr exporta ambas. Usa la que use tu equipo y sé consistente.

Coddy programming languages illustration

Aprende a programar con Coddy

COMENZAR