Tema 03 - Anexo: chuleta de funciones auxiliares

Material de consulta: qué función usar para cada tarea

Pedro Albarrán

Dpto. de Fundamentos del Análisis Económico. Universidad de Alicante

Cómo usar este anexo

Esto NO es una clase

  • Este anexo es una chuleta: no hay que estudiarlo ni memorizarlo

  • Está ordenado por para qué sirve cada función, no por orden de dificultad

  • Se consulta cuando en un ejercicio hace falta hacer algo concreto y no sabemos con qué función

    • Ej.: “quiero quedarme con todas las columnas que empiezan por id_” \(\rightarrow\) Elegir columnas
  • Todo lo que aquí aparece se explica en clase cuando surge en un ejercicio

  • Chuletas oficiales, más completas: https://posit.co/resources/cheatsheets/

Elegir columnas

Auxiliares de select()

# Por rango de columnas
ventas |> select(id_venta:id_tienda)

# Excluir columnas
ventas |> select(-descuento_porcentaje, -descuento_aplicado)

# Por patrón de nombre
ventas |> select(starts_with("id_"))
ventas |> select(ends_with("_porcentaje"))
ventas |> select(contains("descuento"))

# Por tipo de dato
ventas |> select(where(is.numeric))
ventas |> select(where(is.character))
  • pull(): extrae una única columna, como vector (no como tabla)
ventas |> pull(cantidad) |> mean()

Cambiar nombre y orden de columnas

  • rename(): cambiar el nombre de una columna
ventas_renamed <- ventas |>
  rename(fecha_venta = fecha,
         monto_total = total)
  • relocate(): cambiar el orden de las columnas
ventas |>
  relocate(total, .after = fecha) |>
  relocate(starts_with("id_"), .before = everything())
  • everything(): “todas las demás”, útil para poner unas pocas delante
ventas |> select(id_venta, fecha, total, everything())

Elegir filas

Auxiliares para extraer filas

  • Extraer filas pero NO por condición: por posición (slice(), slice_head()), aleatoriamente (slice_sample()), por valor (slice_max()), etc.
ventas |> slice_max(total, n = 5) # Top 5 ventas
ventas |> slice_sample(n = 100)   # sub-muestra aleatoria
  • distinct(): extrae sólo las filas únicas (de una o varias variables)
ventas |> distinct(id_producto)
ventas |> distinct(id_producto, .keep_all = TRUE) # conserva el resto de columnas

Filas con valores ausentes (NA)

  • drop_na() y replace_na(): elimina/reemplaza filas con valores ausentes
ventas_completas <- ventas |> drop_na()        # NA en cualquier variable

ventas_con_empleado <- ventas |>               # solo si falta el empleado
  drop_na(id_empleado)                         # (venta online)
  • Eliminar NA, PERO:

    • en alguna variable: na.rm = TRUE o filter(!is.na(x)) o drop_na(x)
    • en todo el conjunto de datos: drop_na()
  • Reemplazar por un valor, PERO ¿cuál?

    • NA por no presentarse a un examen es cero
    • NA por no contestar a la pregunta de renta, ¿es cero?
datos <- tibble(x1 = c(1:4, NA, 6, 7, NA))

datos |> mutate(x1 = if_else(is.na(x1), 0, x1))
datos |> mutate(x1 = replace_na(x1, 0))

Crear y transformar variables

Condicionales y discretización

  • if_else() y case_when() para ejecución condicional (ifelse() en R base)
ventas |>
  mutate(
    tipo_venta = if_else(total > 1000, "Alta", "Baja"), # condición simple
    categoria_cliente = case_when(              # múltiples condiciones
      total < 300  ~ "Económico",
      total < 1000 ~ "Estándar",
      TRUE         ~ "Premium"               # OJO: convertir a factor
    )
  )
  • Discretizar variables: cut_interval(), cut_number(), cut_width()
ventas |> mutate(tramo = cut_width(total, 250))   # tramo es factor

Aplicar la misma transformación a varias columnas

  • across(): aplica la misma transformación a múltiples columnas
ventas |> mutate(across(c(cantidad, subtotal:total), ~ log(.x)))
ventas |> mutate(across(where(is.character), ~ parse_factor(.x)))
  • Muchas funciones son equivalentes a otras de R base:

    • parse_number(), parse_factor(), etc. por as.numeric(), as.factor(), etc.
    • bind_cols() y bind_rows() por cbind() y rbind()
  • Operadores aritméticos (+, -, *, /, ^, %/%, %%) y lógicos (<, <=, >, >=, !=)

Funciones útiles dentro de mutate()

  • Funciones como log(), lag(), lead(), cumsum(), row_number()
ventas |> group_by(id_tienda) |> arrange(fecha) |>
  mutate(venta_anterior = lag(total),                 # fila anterior
         acumulado      = cumsum(total),              # suma acumulada
         orden          = row_number()) |> ungroup()  # 1, 2, 3, ...
  • Combinadas con funciones de “agregación”: x - mean(x), y / sum(y)

Fechas (lubridate)

  • Funciones para extraer partes de una fecha: year(), month(), day(), quarter(), week(), wday()
ventas |>
  mutate(
    año        = year(fecha),
    mes        = month(fecha),
    trimestre  = quarter(fecha),
    mes_nombre = month(fecha, label = TRUE, abbr = FALSE),
    dia_semana = wday(fecha, label = TRUE, abbr = FALSE),
    es_finde   = wday(fecha) %in% c(1, 7)
  )
  • Diferencias entre fechas
ventas |> mutate(dias_desde_hoy = as.numeric(Sys.Date() - fecha))

Resumir

Contar

  • count(): cuenta los valores únicos de una o más variables
ventas |> count(id_tienda)
# equivale a: ventas |> group_by(id_tienda) |> summarize(n = n())
ventas |> count(id_tienda, sort = TRUE)     # ordenado de mayor a menor
ventas |> count(id_tienda, mes, name = "num_ventas")  # dos variables
  • add_count(): añade la columna de conteo SIN reducir filas
ventas |>
  add_count(id_producto, name = "veces_vendido") |>
  filter(veces_vendido > 50)
  • Conteos dentro de summarize():

    • n(): observaciones totales (tamaño del grupo)
    • n_distinct(x): número de valores distintos de x

Funciones de resumen dentro de summarize()

  • Centralidad y dispersión: mean(x), median(x), sd(x), IQR(x)

  • Rango: min(x), quantile(x, 0.25), max(x)

  • Posición: first(x), nth(x, 2), last(x)

  • Sumas y productos: sum(x), prod(x)

  • Conteos: n(), n_distinct(x)

ventas |>
  summarize(
    media    = mean(total),  desv_std = sd(total),
    minimo   = min(total),   q25      = quantile(total, 0.25),
    mediana  = median(total), q75     = quantile(total, 0.75),
    maximo   = max(total),   rango_ic = IQR(total)
  )

Agrupar sin group_by(): el argumento .by =

Forma moderna (dplyr 1.1 o posterior)

mutate(), summarize(), filter() y slice() aceptan .by =, que agrupa solo para esa operación. Hace lo mismo que group_by() y evita de raíz el problema de quedarse agrupado.

ventas |> summarize(ingresos = sum(total), .by = id_tienda)
ventas |> mutate(ventas_tienda = sum(total), .by = id_tienda)

Tres diferencias con group_by():

  1. El resultado sale siempre desagrupado, así que desaparece el fallo de “se me quedó agrupado” y no hace falta ungroup() ni .groups = "drop".
  2. No reordena las filas. group_by() ordena por la clave; .by = deja el orden original.
  3. Hace menos copias, lo que se nota con millones de filas.

Con varias claves hay que envolverlas: .by = c(id_tienda, mes).

En el curso se enseña group_by(), porque es lo que vais a encontrar en la documentación, en los ejemplos de internet y en el código de otros. .by = es el atajo una vez entendido lo que hace la agrupación.

Ancho o largo: qué tareas se complican

Con formato ancho, algunas tareas son imposibles

  • Según nuestros objetivos, podemos preferir formato ancho o largo

  • Problemas prácticos del formato ancho para analizar datos:

  1. Algunas tareas son imposibles. P.e., ¿qué trimestres superan 160 en ventas?
ventas_largo |>
  filter(ventas > 160)
  1. Código repetitivo y propenso a errores. P.e., calcular el crecimiento
ventas_ancho |>
  mutate(
    crec_Q2 = (Q2 - Q1) / Q1 * 100,
    crec_Q3 = (Q3 - Q2) / Q2 * 100,
    crec_Q4 = (Q4 - Q3) / Q3 * 100
  )

ventas_largo |>
  group_by(tienda) |>
  mutate(crecimiento = (ventas - lag(ventas)) / lag(ventas) * 100)

Con formato ancho, algunas tareas son imposibles (cont.)

  1. No escalable. P.e., gráfico temporal por grupos
ggplot(ventas_ancho) +
  geom_line(aes(x = 1:4, y = c(Q1[1], Q2[1], Q3[1], Q4[1])), color = "red") +
  geom_line(aes(x = 1:4, y = c(Q1[2], Q2[2], Q3[2], Q4[2])), color = "blue") +
  geom_line(aes(x = 1:4, y = c(Q1[3], Q2[3], Q3[3], Q4[3])), color = "green")

ggplot(ventas_largo, aes(x = trimestre, y = ventas,
                         color = tienda, group = tienda)) +
  geom_line() + geom_point()
  • Formato ancho solo para tablas de presentación final
tabla_presentacion <- ventas_largo |>
  pivot_wider(names_from = trimestre, values_from = ventas) |>
  mutate(Total = Q1 + Q2 + Q3 + Q4)