Skip to content

Canalización de limpieza de datos con R dplyr: de datos crudos a tablas limpias

Problema

Las personas analistas pierden tiempo escribiendo bucles repetitivos en R para limpiar conjuntos de datos. El resultado son scripts frágiles, columnas inconsistentes e iteraciones lentas cada vez que llega un nuevo archivo.

Agravar

Los pasos manuales se acumulan: seleccionar columnas incorrectas, aplicar transformaciones en el orden equivocado o olvidar manejar factores frente a caracteres. Cada error obliga a re‑ejecutar el flujo y aumenta el riesgo de enviar métricas incorrectas a los paneles de control posteriores.

Solución

Adopta una canalización consistente con dplyr que refleje la lógica de SQL y mantenga cada transformación legible. Los verbos siguientes cubren selección de columnas, filtrado de filas, creación de nuevas variables, resúmenes, ordenamiento y joins seguros para que los datos queden ordenados antes del modelado o la visualización.

Canalización básica en acción

library(dplyr)
 
clean_sales <- raw_sales %>%
  mutate(
    region = as.character(region),        # avoid accidental factor levels
    revenue = price * quantity
  ) %>%
  filter(!is.na(revenue), revenue > 0) %>%
  select(order_id, region, revenue, channel, order_date) %>%
  arrange(desc(revenue)) %>%
  group_by(region, channel) %>%
  summarise(
    orders = n(),
    revenue = sum(revenue),
    avg_order = mean(revenue),
    .groups = "drop"
  )

Verbos de dplyr y sus equivalentes en SQL

dplyr verbPropósitoAnalogía en SQLNota rápida
select()conservar o renombrar columnasSELECT col1, col2Usa everything() para reordenar rápidamente.
filter()subconjuntos de filasWHERE conditionCombínalo con %in% para múltiples valores.
mutate()agregar/transformar columnasSELECT col1, col2*2 AS col2xPrefiere if_else() para lógica con tipos estables.
summarise() + group_by()métricas agrupadasGROUP BY ...Agrega .groups = "drop" para desagrupar.
arrange()ordenar filasORDER BYUsa desc() para orden descendente.
left_join()enriquecer con tablas de referenciaLEFT JOINMantén las claves de join del mismo tipo (character vs factor).
bind_rows() / bind_cols()apilar o ensanchar tablasUNION ALL / concatenación de columnasAsegura esquemas compatibles al apilar.

Joins vs. binds de un vistazo

# Join: add columns from a lookup table
sales_with_regions <- sales %>%
  left_join(region_lookup, by = "region_id")
 
# Bind: stack identical schemas
all_sales <- bind_rows(sales_2023, sales_2024)

Evitar problemas con factors y codificación

  • Convierte identificadores a character antes de hacer joins para evitar niveles no coincidentes.
  • Usa mutate(across(where(is.factor), as.character)) si un CSV se leyó con factors implícitos.
  • Estandariza texto con stringr::str_trim y tolower antes de agrupar para evitar categorías duplicadas.

Plantilla rápida de inicio

prep_data <- function(df) {
  df %>%
    mutate(across(where(is.factor), as.character)) %>%
    filter(!is.na(key_id)) %>%
    distinct() %>%
    select(key_id, everything())
}

Lista de verificación antes de guardar

  • Las columnas están explícitamente seleccionadas y ordenadas.
  • Los joins clave usan tipos coincidentes y sufijos claros cuando es necesario (suffix = c(".src", ".lkp")).
  • Los resúmenes eliminan el agrupamiento para evitar sorpresas en pasos posteriores.
  • Las salidas contienen solo columnas limpias y legibles para personas, listas para gráficos o modelos.

Guías relacionadas