R
Tutorial R: dplyr para filtrado y selección
Aprende a usar dplyr en R para filtrar y seleccionar datos con filter(), select() y el operador pipe para análisis eficiente.
Aprende R y certifícatefilter() para subconjuntos por condición
La función filter()
es una de las herramientas más útiles del paquete dplyr, diseñada específicamente para extraer subconjuntos de filas de un dataframe que cumplan con una o varias condiciones lógicas. A diferencia del método tradicional de indexación en R base, filter()
ofrece una sintaxis más intuitiva y legible.
Funcionamiento básico
La función filter()
evalúa cada fila de un dataframe y conserva únicamente aquellas que cumplen con las condiciones especificadas. Su sintaxis general es:
filter(dataframe, condición1, condición2, ...)
Donde cada condición es una expresión que devuelve un valor lógico (TRUE
o FALSE
). Veamos un ejemplo sencillo utilizando el dataset mtcars
que viene incluido en R:
# Cargar la librería dplyr
library(dplyr)
# Filtrar coches con más de 100 caballos de potencia
coches_potentes <- filter(mtcars, hp > 100)
# Mostrar las primeras filas del resultado
head(coches_potentes)
En este ejemplo, filter()
evalúa la condición hp > 100
para cada fila y conserva solo aquellas donde esta condición es verdadera.
Operadores de comparación
Para crear condiciones efectivas, podemos utilizar los operadores de comparación estándar de R:
>
(mayor que)>=
(mayor o igual que)<
(menor que)<=
(menor o igual que)==
(igual a)!=
(distinto de)
Por ejemplo, para filtrar coches con un consumo de combustible específico:
# Filtrar coches con exactamente 21 millas por galón
coches_21mpg <- filter(mtcars, mpg == 21)
# Ver el resultado
coches_21mpg
Combinando múltiples condiciones
Una de las ventajas de filter()
es la facilidad para combinar múltiples condiciones. Cuando pasamos varias condiciones separadas por comas, estas se combinan con el operador lógico AND (&
), lo que significa que todas deben cumplirse:
# Filtrar coches con más de 100 caballos y menos de 3000 libras de peso
coches_filtrados <- filter(mtcars, hp > 100, wt < 3)
# Ver el resultado
head(coches_filtrados)
Para utilizar condiciones OR (|
), AND (&
) o NOT (!
), podemos incluirlas explícitamente:
# Coches muy potentes O muy ligeros
coches_especiales <- filter(mtcars, hp > 200 | wt < 2.5)
# Coches que NO son automáticos (am = 0 significa transmisión manual)
coches_manuales <- filter(mtcars, !am == 0)
Trabajando con valores NA
Al filtrar datos, es importante considerar cómo manejar los valores NA (datos faltantes). Por defecto, filter()
excluye las filas donde la condición evalúa a NA
. Para incluir explícitamente o excluir valores NA, podemos usar la función is.na()
:
# Crear un dataframe de ejemplo con algunos NA
df <- data.frame(
x = c(1, 2, NA, 4, 5),
y = c("a", "b", "c", NA, "e")
)
# Filtrar filas donde x no es NA
filter(df, !is.na(x))
# Filtrar filas donde y es NA
filter(df, is.na(y))
Filtrado con operadores %in%
El operador %in%
es extremadamente útil cuando queremos filtrar filas donde una columna coincida con cualquier valor de un conjunto:
# Crear un dataframe de ejemplo
empleados <- data.frame(
nombre = c("Ana", "Carlos", "Elena", "David", "Beatriz"),
departamento = c("Ventas", "IT", "Marketing", "IT", "Ventas"),
edad = c(28, 35, 42, 31, 29)
)
# Filtrar empleados de departamentos específicos
it_marketing <- filter(empleados, departamento %in% c("IT", "Marketing"))
# Ver el resultado
it_marketing
Filtrado por patrones de texto
Para filtrar basándonos en patrones de texto, podemos combinar filter()
con funciones de manipulación de strings como grepl()
o str_detect()
del paquete stringr:
# Filtrar nombres que empiezan con la letra A
nombres_con_a <- filter(empleados, grepl("^A", nombre))
# Con stringr sería:
# library(stringr)
# nombres_con_a <- filter(empleados, str_detect(nombre, "^A"))
# Ver el resultado
nombres_con_a
Filtrado por rangos
Para filtrar valores dentro de un rango, podemos usar el operador between()
que proporciona dplyr:
# Filtrar empleados con edades entre 30 y 40 años
edad_media <- filter(empleados, between(edad, 30, 40))
# Equivalente a:
# edad_media <- filter(empleados, edad >= 30 & edad <= 40)
# Ver el resultado
edad_media
Ejemplo práctico con un dataset real
Veamos un ejemplo más completo utilizando el dataset iris
, que contiene medidas de diferentes especies de flores:
# Cargar dplyr
library(dplyr)
# Filtrar flores de la especie setosa con ancho de sépalo mayor a 4
setosa_grandes <- filter(iris,
Species == "setosa",
Sepal.Width > 4)
# Ver el resultado
setosa_grandes
# Filtrar flores que no son virginica y tienen longitud de pétalo entre 4 y 5
flores_seleccionadas <- filter(iris,
Species != "virginica",
between(Petal.Length, 4, 5))
# Ver cuántas filas cumplen estas condiciones
nrow(flores_seleccionadas)
La función filter()
es una herramienta fundamental para la exploración y limpieza de datos en R. Su sintaxis clara y su capacidad para combinar múltiples condiciones la convierten en una opción superior a los métodos tradicionales de indexación para muchas tareas de análisis de datos.
select() y helpers para elegir columnas
Mientras que filter()
nos permite trabajar con filas, la función select()
de dplyr nos proporciona una forma elegante y eficiente de seleccionar columnas específicas de un dataframe. Esta función resulta especialmente útil cuando trabajamos con conjuntos de datos que contienen numerosas variables y solo necesitamos un subconjunto de ellas.
La sintaxis básica de select()
es muy intuitiva:
select(dataframe, columna1, columna2, ...)
Veamos un ejemplo sencillo utilizando el dataset iris
:
library(dplyr)
# Seleccionar solo las columnas de longitud
iris_longitud <- select(iris, Sepal.Length, Petal.Length)
# Mostrar las primeras filas
head(iris_longitud)
Este código crea un nuevo dataframe que contiene únicamente las columnas de longitud del sépalo y del pétalo, descartando las demás variables.
Selección por posición y nombre
Podemos seleccionar columnas tanto por su nombre como por su posición:
# Por nombre
especies_y_sepalo <- select(iris, Species, Sepal.Length)
# Por posición
primeras_tres <- select(iris, 1:3)
# Combinando ambos métodos
mix_seleccion <- select(iris, Species, 1:2)
Excluyendo columnas
Para excluir columnas específicas en lugar de seleccionarlas, podemos utilizar el signo menos (-
):
# Seleccionar todas las columnas excepto Species
sin_especies <- select(iris, -Species)
# Excluir múltiples columnas
solo_petalos <- select(iris, -Sepal.Length, -Sepal.Width)
# Excluir un rango de columnas
sin_sepalo <- select(iris, -(1:2))
Reordenando columnas
La función select()
también nos permite reordenar las columnas de un dataframe:
# Colocar Species al principio
especies_primero <- select(iris, Species, everything())
# Reordenar completamente
reordenado <- select(iris, Petal.Length, Petal.Width, Sepal.Length, Sepal.Width, Species)
Funciones helper para select()
Dplyr proporciona varias funciones auxiliares (helpers) que hacen que la selección de columnas sea aún más potente y flexible. Estas funciones están diseñadas para trabajar específicamente con select()
:
1. starts_with()
, ends_with()
y contains()
Estas funciones nos permiten seleccionar columnas basándonos en patrones en sus nombres:
# Seleccionar columnas que empiezan con "Sepal"
solo_sepalo <- select(iris, starts_with("Sepal"))
# Seleccionar columnas que terminan con "Width"
anchuras <- select(iris, ends_with("Width"))
# Seleccionar columnas que contienen "etal"
variables_petal <- select(iris, contains("etal"))
2. matches()
Permite seleccionar columnas cuyos nombres coinciden con una expresión regular:
# Seleccionar columnas que contienen "al"
con_al <- select(iris, matches("al"))
# Seleccionar columnas que empiezan con S o P
sp_cols <- select(iris, matches("^[SP]"))
3. everything()
Esta función selecciona todas las columnas restantes, lo que resulta útil para reordenar columnas:
# Mover Species al principio y mantener el resto en el mismo orden
especies_primero <- select(iris, Species, everything())
4. num_range()
Permite seleccionar columnas con nombres que siguen un patrón numérico:
# Crear un dataframe de ejemplo con columnas numeradas
df_numerado <- data.frame(
x1 = 1:3,
x2 = 4:6,
x3 = 7:9,
y = c("a", "b", "c")
)
# Seleccionar columnas x1, x2 y x3
solo_x <- select(df_numerado, num_range("x", 1:3))
5. one_of()
Selecciona columnas cuyos nombres están en un vector de caracteres:
variables <- c("Sepal.Length", "Petal.Length", "Species")
longitudes_y_especie <- select(iris, one_of(variables))
6. where()
Permite seleccionar columnas basándose en una función predicado:
# Seleccionar solo columnas numéricas
numericas <- select(iris, where(is.numeric))
# Seleccionar columnas con valores únicos > 10
muchos_valores <- select(iris, where(~length(unique(.)) > 10))
Renombrando columnas con select()
Podemos renombrar columnas al mismo tiempo que las seleccionamos utilizando la sintaxis nuevo_nombre = viejo_nombre
:
# Renombrar columnas de longitud
renombrado <- select(iris,
longitud_sepalo = Sepal.Length,
longitud_petalo = Petal.Length)
# Renombrar algunas y mantener otras
mix_renombrado <- select(iris,
longitud_sepalo = Sepal.Length,
Sepal.Width,
longitud_petalo = Petal.Length,
Petal.Width,
especie = Species)
Ejemplo práctico con un dataset real
Veamos un ejemplo más completo utilizando el dataset mtcars
:
# Cargar dplyr
library(dplyr)
# Seleccionar variables relacionadas con el rendimiento
rendimiento <- select(mtcars, mpg, hp, qsec)
# Seleccionar variables de tamaño y renombrarlas
dimensiones <- select(mtcars,
peso = wt,
cilindrada = disp,
starts_with("c"))
# Reorganizar las columnas: primero el nombre del coche, luego rendimiento, después el resto
mtcars_reorganizado <- mtcars %>%
# Convertir los nombres de fila a una columna llamada "coche"
rownames_to_column("coche") %>%
select(coche, mpg, hp, everything())
# Ver el resultado
head(mtcars_reorganizado)
La función select()
y sus helpers nos permiten manipular las columnas de nuestros dataframes de manera eficiente y expresiva, facilitando enormemente el trabajo con conjuntos de datos complejos. Combinada con otras funciones de dplyr, nos proporciona un conjunto de herramientas poderoso para la manipulación de datos en R.
Operaciones encadenadas con pipe
El operador pipe (%>%
) es una de las innovaciones más importantes en el ecosistema de R, especialmente dentro del tidyverse. Este operador, proporcionado por el paquete magrittr e incorporado en dplyr, permite encadenar múltiples operaciones de manera secuencial y legible, transformando radicalmente la forma en que escribimos código para análisis de datos.
El pipe toma el resultado de una expresión y lo pasa como primer argumento a la siguiente función. Su sintaxis básica es:
datos %>% funcion()
Que equivale a:
funcion(datos)
Aunque esta equivalencia parece trivial en operaciones simples, el verdadero poder del pipe se revela cuando encadenamos múltiples operaciones.
Ventajas del pipe en la manipulación de datos
Trabajar con el pipe ofrece varias ventajas significativas:
- Legibilidad: El código fluye de izquierda a derecha y de arriba a abajo, siguiendo el orden natural de lectura.
- Mantenimiento: Evita la creación de variables intermedias o la anidación excesiva de funciones.
- Modularidad: Facilita añadir, eliminar o reordenar pasos en el análisis.
Veamos un ejemplo comparativo. Sin usar pipe, podríamos escribir:
# Sin pipe: anidación de funciones (difícil de leer)
head(select(filter(iris, Sepal.Length > 7), Species, Sepal.Length))
# Sin pipe: usando variables intermedias (código más largo)
iris_filtrado <- filter(iris, Sepal.Length > 7)
iris_seleccionado <- select(iris_filtrado, Species, Sepal.Length)
head(iris_seleccionado)
Con el pipe, el mismo código se transforma en:
# Con pipe: flujo natural y legible
iris %>%
filter(Sepal.Length > 7) %>%
select(Species, Sepal.Length) %>%
head()
Combinando filter() y select() con pipe
La combinación de filter()
y select()
mediante pipes es uno de los patrones más comunes en el análisis de datos con dplyr. Veamos algunos ejemplos prácticos:
library(dplyr)
# Filtrar y luego seleccionar columnas
iris %>%
filter(Species == "virginica") %>%
select(starts_with("Petal"))
# Seleccionar primero y luego filtrar
iris %>%
select(Species, contains("Length")) %>%
filter(Sepal.Length > 6.5)
El orden de las operaciones es importante. Si filtramos primero, podemos reducir significativamente el número de filas antes de seleccionar columnas. Si seleccionamos primero, podemos trabajar con un conjunto más pequeño de variables, lo que puede hacer que las condiciones de filtrado sean más manejables.
Encadenando múltiples operaciones
El pipe brilla especialmente cuando necesitamos realizar múltiples transformaciones secuenciales:
mtcars %>%
# Convertir nombres de fila a columna
rownames_to_column("modelo") %>%
# Filtrar coches con buena eficiencia de combustible
filter(mpg > 20) %>%
# Seleccionar solo algunas columnas
select(modelo, mpg, hp, wt) %>%
# Ordenar por potencia (hp) descendente
arrange(desc(hp)) %>%
# Mostrar solo los primeros 5
head(5)
Este código realiza cinco operaciones distintas de manera clara y concisa, sin necesidad de variables intermedias ni funciones anidadas.
Uso de pipe con funciones que no son de dplyr
El pipe no está limitado a funciones de dplyr; podemos usarlo con cualquier función de R donde los datos sean el primer argumento:
# Crear un gráfico con ggplot2 después de filtrar y seleccionar
library(ggplot2)
iris %>%
filter(Species != "setosa") %>%
select(Species, Sepal.Length, Petal.Length) %>%
ggplot(aes(x = Sepal.Length, y = Petal.Length, color = Species)) +
geom_point() +
labs(title = "Relación entre longitudes de sépalo y pétalo")
Observa que después de ggplot()
usamos +
en lugar de %>%
, ya que esa es la sintaxis específica de ggplot2 para añadir capas al gráfico.
Cuando el resultado no es el primer argumento
En ocasiones, necesitamos usar el resultado de una operación como un argumento que no es el primero en la siguiente función. Para estos casos, podemos usar el marcador de posición .
:
iris %>%
filter(Species == "versicolor") %>%
# Usar el resultado como segundo argumento de cor()
summarise(correlacion = cor(Sepal.Length, Petal.Length, data = .))
Sin embargo, en dplyr moderno, rara vez necesitamos usar este marcador, ya que las funciones están diseñadas para trabajar bien con el pipe.
Ejemplo práctico: análisis exploratorio básico
Veamos un ejemplo más completo que muestra cómo el pipe facilita un flujo de trabajo exploratorio:
library(dplyr)
# Análisis exploratorio del dataset mtcars
mtcars %>%
# Añadir nombres de coche como columna
rownames_to_column("coche") %>%
# Filtrar coches con transmisión automática (am = 0)
filter(am == 0) %>%
# Seleccionar variables relevantes
select(coche, mpg, hp, wt, cyl) %>%
# Ordenar por eficiencia de combustible
arrange(desc(mpg)) %>%
# Agrupar por número de cilindros
group_by(cyl) %>%
# Calcular promedios por grupo
summarise(
n_coches = n(),
mpg_promedio = mean(mpg),
hp_promedio = mean(hp),
peso_promedio = mean(wt)
) %>%
# Ordenar por número de cilindros
arrange(cyl)
Este análisis completo se expresa como un flujo coherente de operaciones, fácil de leer y modificar.
Buenas prácticas al usar pipes
Para aprovechar al máximo el pipe, considera estas recomendaciones:
- Coloca cada operación en una nueva línea e indenta consistentemente para mejorar la legibilidad.
- Limita las cadenas de pipe a operaciones relacionadas; si el análisis cambia de dirección, considera iniciar una nueva cadena.
- Añade comentarios antes de cada paso para documentar el propósito de cada operación.
- Si una cadena se vuelve demasiado larga (más de 10 operaciones), considera dividirla en partes lógicas.
# Ejemplo de formato recomendado
datos_procesados <- datos_crudos %>%
# Eliminar filas con valores faltantes
filter(!is.na(variable_clave)) %>%
# Seleccionar solo las variables necesarias
select(id, starts_with("valor")) %>%
# Ordenar por id
arrange(id)
Alternativas al pipe de magrittr
En versiones recientes de R (≥ 4.1.0), se introdujo el operador pipe nativo |>
que funciona de manera similar al %>%
de magrittr:
# Pipe nativo de R (R ≥ 4.1.0)
iris |>
filter(Species == "setosa") |>
select(starts_with("Petal"))
La principal diferencia es que el pipe nativo no admite el marcador de posición .
para usos avanzados, aunque para la mayoría de los casos de uso con dplyr, ambos operadores funcionan de manera equivalente.
El pipe ha transformado la forma en que escribimos código en R, haciendo que las operaciones secuenciales sean más intuitivas y legibles. Combinado con las funciones de dplyr como filter()
y select()
, proporciona una forma poderosa y expresiva de manipular datos, permitiéndonos concentrarnos en el análisis en lugar de en la sintaxis.
Otros ejercicios de programación de R
Evalúa tus conocimientos de esta lección dplyr para filtrado y selección con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
Todas las lecciones de R
Accede a todas las lecciones de R y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Instalación De R Y Rstudio
Introducción Y Entorno
Introducción A R
Introducción Y Entorno
Operadores
Sintaxis
Estructuras De Datos
Sintaxis
Funciones
Sintaxis
Estructuras De Control Iterativo
Sintaxis
Scopes Y Closures
Sintaxis
Estructuras De Control Condicional
Sintaxis
Funciones Anónimas
Sintaxis
Tipos De Datos Y Variables
Sintaxis
Sistema R6: Clases Referenciales Y Encapsulamiento
Programación Orientada A Objetos
Sistema S4: Clases Formales Y Validación
Programación Orientada A Objetos
Herencia Y Polimorfismo En R
Programación Orientada A Objetos
Sistemas De Oop En R
Programación Orientada A Objetos
Sistema S3: Clases Implícitas Y Métodos Genéricos
Programación Orientada A Objetos
Tidyverse Para Transformación De Datos
Manipulación De Datos
Lubridate Para Fechas Y Tiempo
Manipulación De Datos
Group_by Y Summarize Para Agrupación Y Resumen
Manipulación De Datos
Stringr Para Expresiones Regulares
Manipulación De Datos
Tidyr Para Limpieza De Valores Faltantes
Manipulación De Datos
Joins En R Para Combinación Y Relaciones De Tablas
Manipulación De Datos
Pivot_longer Y Pivot_wider Para Reestructuración
Manipulación De Datos
Mutate Y Transmute Para Transformación
Manipulación De Datos
Dplyr Para Filtrado Y Selección
Manipulación De Datos
Readr Y Read.csv Para Importar Datos
Manipulación De Datos
Gráficos Bivariantes En R
Visualización De Datos
Gráficos Univariantes En R
Visualización De Datos
Facetas En Ggplot2
Visualización De Datos
Personalización Y Temas
Visualización De Datos
Ggplot2 Para Visualización De Datos
Visualización De Datos
Gráficos Multivariantes En R
Visualización De Datos
Correlación En R
Estadística
Regresión Lineal En R
Estadística
Pruebas De Hipótesis En R
Estadística
Anova En R
Estadística
Estadística Descriptiva En R
Estadística
En esta lección
Objetivos de aprendizaje de esta lección
- Comprender el uso de filter() para extraer subconjuntos de filas según condiciones lógicas.
- Aprender a seleccionar columnas específicas con select() y sus funciones auxiliares.
- Manejar combinaciones de condiciones lógicas y valores NA en el filtrado.
- Aplicar el operador pipe (%>%) para encadenar operaciones de manera clara y modular.
- Realizar análisis exploratorios básicos combinando filter(), select() y pipes en datasets reales.