Introducción

En el análisis de datos moderno en R, la manipulación eficiente de tablas (data frames y tibbles) se realiza principalmente a través del paquete dplyr, el cual forma parte del ecosistema tidyverse.

dplyr proporciona una “gramática para la manipulación de datos”, basada en verbos de acción simples e intuitivos que permiten estructurar código de forma clara, legible y modular.

Librerías que utilizaremos en esta clase

Para dominar la transformación completa de datos, utilizaremos las siguientes librerías:

  1. dplyr: Paquete principal para filtrar, seleccionar, transformar, reordenar y resumir datos (select, filter, arrange, mutate, summarise, group_by, case_when).
  2. tibble: Herramientas para trabajar con tablas modernas. En particular, la función rownames_to_column() nos permitirá convertir los nombres de filas del dataset mtcars en una verdadera columna manipulable.
  3. stringr: Manipulación y extracción de cadenas de texto mediante funciones como str_sub().
  4. tidyr: Ordenación y estructuración de tablas, con funciones como separate() (dividir columnas) y unite() (combinar columnas).
  5. pwt10: Paquete que contiene la base de datos macroeconómica Penn World Table 10.0 (pwt10.01), ideal para aplicar los verbos en series temporales de contabilidad nacional.
library(dplyr)
library(tibble)
library(stringr)
library(tidyr)
library(pwt10)

El Operador Tubería (Pipe): %>% o |>

El operador Pipe permite encadenar operaciones secuenciales de forma lógica y legible. En lugar de anidar funciones unas dentro de otras (f(g(x))), leemos el código de izquierda a derecha y de arriba abajo, como si fuera una receta de cocina:

\[ {datos} \longrightarrow {filtrar} \longrightarrow {seleccionar} \longrightarrow {transformar} \longrightarrow {resumir}\]


Preparación de la Base de Datos Para Ejemplos: mtcars

El dataset nativo de R mtcars contiene especificaciones técnicas y rendimiento de 32 automóviles (modelos 1973-1974).

Punto Clave: En R tradicional, los nombres de los vehículos en mtcars están guardados como nombres de fila (rownames) y no como una columna normal. Para poder aplicar verbos de dplyr sobre los nombres de los carros, primero usaremos tibble::rownames_to_column().

autos <- mtcars %>% 
  rownames_to_column(var = "modelo")

head(autos)

1. Seleccionar Columnas: select()

El verbo select() nos permite elegir únicamente las columnas (variables) que necesitamos para nuestro análisis, descartando las innecesarias o cambiando su orden.

1.1 Selección Básica por Nombre

autos_sub <- autos %>% 
  select(modelo, mpg, hp, wt)

head(autos_sub)

1.2 Helper Functions (Funciones de Ayuda)

dplyr incluye funciones auxiliares para seleccionar columnas según patrones en sus nombres:

  • starts_with("p"): Columnas que empiezan con “p”.
  • ends_with("g"): Columnas que terminan con “g”.
  • contains("a"): Columnas que contienen la letra “a”.
  • everything(): Representa todas las demás columnas (útil para reordenar).
autos %>% 
  select(modelo, ends_with("p"), ends_with("g")) %>% 
  head()
autos %>% 
  select(modelo, hp, cyl, everything()) %>% 
  head()

2. Filtrar Observaciones (Filas): filter()

El verbo filter() extrae únicamente aquellas filas que cumplen con una o más condiciones lógicas.

2.1 Operadores de Comparación y Lógicos

Operador Significado Operador Significado
== Igual a & Y lógico (AND)
!= Diferente de \| O lógico (OR)
> / < Mayor / Menor que %in% Pertenece a un conjunto
>= / <= Mayor/Menor o igual is.na() Es valor faltante (NA)

2.2 Ejemplos de Filtrado

autos %>% 
  filter(mpg > 25) %>% 
  select(modelo, mpg, cyl, hp)
autos %>% 
  filter(hp > 200 & cyl == 8) %>% 
  select(modelo, hp, cyl, wt)
autos %>% 
  filter(cyl %in% c(4, 6)) %>% 
  select(modelo, cyl, mpg) %>% 
  head(6)

3. Ordenar Filas: arrange()

El verbo arrange() reordena las filas de una tabla según los valores de una o más columnas.

  • Por defecto, el orden es ascendente (de menor a mayor).
  • Para orden descendente (de mayor a menor), envolvemos la columna con desc().
autos %>% 
  select(modelo, mpg, hp, cyl) %>% 
  arrange(mpg) %>% 
  head(5)
autos %>% 
  select(modelo, hp, mpg, cyl) %>% 
  arrange(desc(hp)) %>% 
  head(5)
autos %>% 
  select(modelo, cyl, mpg, hp) %>% 
  arrange(cyl, desc(mpg)) %>% 
  head(8)

4. Crear y Modificar Variables: mutate()

El verbo mutate() permite computar nuevas columnas o modificar las existentes mediante cálculos matemáticos, conversiones o funciones condicionales.

4.1 Transformaciones Aritméticas

En el dataset mtcars: * mpg: Millas por Galón.

  • Multiplica el valor de la variable mpg por 0.425144.Por ejemplo, un rendimiento de 20 mpg equivale aproximadamente a 8.50 kpl.
  • Multiplica el valor de la variable wt por 453.592 (que es el resultado directo de multiplicar 1000 por 0.453592). Por ejemplo, un peso wt de 3.2 (3,200 libras) equivale aproximadamente a 1,451.5 kilogramos.
autos_transformados <- autos %>% 
  select(modelo, mpg, wt, hp) %>% 
  mutate(
    kpl = mpg * 0.425144,
    peso_kg = wt * 1000 * 0.453592,
    eficiencia_hp = hp / wt
  )

head(autos_transformados)

4.2 Lógica Condicional: case_when()

case_when() es una de las herramientas más potentes de dplyr. Funciona como una serie de sentencias if-else encadenadas para categorizar datos según reglas numéricas o de texto.

\[ {Sintaxis:} {condicion} \sim {"Resultado"}\]

autos_categorizados <- autos %>% 
  select(modelo, mpg, hp, am) %>% 
  mutate(
    categoria_consumo = case_when(
      mpg >= 25 ~ "Económico",
      mpg >= 18 & mpg < 25 ~ "Moderado",
      mpg < 18 ~ "Alto Consumo",
      TRUE ~ "No Clasificado"
    ),
    tipo_transmision = case_when(
      am == 0 ~ "Automático",
      am == 1 ~ "Manual"
    )
  )

head(autos_categorizados, 8)

5. Resumen y Agrupación: summarise() y group_by()

El verbo summarise() (o summarize()) resume un data frame a una sola fila con métricas estadísticas calculadas (media, mediana, desviación estándar, conteo, etc.).

Cuando se combina con group_by(), la agregación se realiza para cada categoría de la variable agrupadora.

5.1 Resumen Global

autos %>% 
  summarise(
    promedio_mpg = mean(mpg),
    mediana_hp   = median(hp),
    maximo_wt    = max(wt),
    total_autos  = n()
  )

5.2 Resumen Agrupado por Categoría

resumen_por_cilindros <- autos %>% 
  group_by(cyl) %>% 
  summarise(
    total_modelos = n(),
    promedio_mpg  = mean(mpg),
    promedio_hp   = mean(hp),
    desv_est_hp   = sd(hp)
  ) %>% 
  arrange(cyl)

resumen_por_cilindros

Buena Práctica: Después de realizar un group_by() y summarise(), es recomendable usar ungroup() si vas a realizar transformaciones adicionales en los datos para evitar comportamientos inesperados en las siguientes funciones.


6. Extracción de Cadenas de Texto: str_sub() (stringr)

La función str_sub() del paquete stringr sirve para extraer o reemplazar partes específicas de una cadena de texto basándose en las posiciones de los caracteres (índices de inicio y fin).

\[ {Sintaxis: } {str\_sub(string, start = inicio, end = fin)}\]

En nuestro dataset autos, los nombres de los modelos comienzan con el nombre de la marca (ej. “Mazda RX4”, “Datsun 710”, “Merc 240D”). Podríamos usar str_sub() para extraer las primeras letras o generar códigos identificadores.

autos_codigo <- autos %>% 
  select(modelo, mpg, hp) %>% 
  mutate(
    codigo_marca = str_sub(modelo, start = 1, end = 3),
    codigo_marca = toupper(codigo_marca),
    nombre_corto = str_sub(modelo, 1, 7)
  )

head(autos_codigo, 6)

7. Manipulación de Columnas de Texto: separate() y unite() (tidyr)

El paquete tidyr complementa a dplyr en la preparación de datos.

  • separate(): Divide una sola columna de texto en varias columnas hijas utilizando un separador (como un espacio " ", guión "-" o coma ",").
  • unite(): Une los valores de dos o más columnas en una sola cadena de texto.

7.1 Dividir Nombres de Autos con separate()

En mtcars, los modelos suelen incluir la marca en la primera palabra (ej. "Mazda RX4" $ ightarrow$ Marca: "Mazda", Modelo: "RX4").

autos_separados <- autos %>% 
  select(modelo, mpg, hp, cyl, am) %>% 
  separate(
    col = modelo, 
    into = c("marca", "submodelo"), 
    sep = " ", 
    extra = "merge", 
    fill = "right" 
  )

head(autos_separados, 8)

7.2 Combinar Columnas con unite()

Supongamos que deseamos crear una etiqueta descriptiva única uniendo el número de cilindros (cyl) y el tipo de transmisión (am).

autos_unidos <- autos_separados %>% 
  mutate(transmision_txt = ifelse(am == 1, "Manual", "Auto")) %>% 
  unite(
    col = "especificacion", 
    cyl, transmision_txt, 
    sep = " cyl - Transmisión "
  )

head(autos_unidos %>% select(marca, submodelo, especificacion, mpg), 6)

8. Resumen

La siguiente tabla condensa la gramática básica trabajada durante esta clase:

Verbo / Función Paquete Propósito Principal Ejemplo Sintáctico
select() dplyr Seleccionar / descartar columnas df %>% select(col1, col2)
filter() dplyr Filtrar observaciones según condición df %>% filter(edad > 18 & sexo == "M")
arrange() dplyr Ordenar filas (ascendente / descendente) df %>% arrange(desc(salario))
mutate() dplyr Crear o modificar variables df %>% mutate(pib_pc = pib / pop)
case_when() dplyr Lógica condicional múltiple dentro de mutate case_when(x > 10 ~ "A", TRUE ~ "B")
summarise() dplyr Colapsar tabla en métricas estadísticas df %>% summarise(media = mean(x))
group_by() dplyr Agrupar datos para cálculos por categoría df %>% group_by(cat) %>% summarise(...)
str_sub() stringr Extraer subcadenas de texto por posición str_sub(texto, start = 1, end = 3)
separate() tidyr Dividir una columna de texto en varias separate(col, into = c("c1","c2"), sep=" ")
unite() tidyr Combinar múltiples columnas en una sola unite(col_nueva, c1, c2, sep = "-")
rownames_to_column() tibble Convertir nombres de filas en columna df %>% rownames_to_column(var = "id")