Analítica de Personas · Semestre otoño 2026 · Semana 2 · Prof. René Gempp
En el Apunte 1 cubrimos las funciones básicas de dplyr: count(), filter(), group_by(), summarise(), select(), mutate() y arrange(). Este apunte amplía el repertorio con funciones que usarás constantemente a partir de la Clase 2.
mutate() en profundidadYa sabes que mutate() crea o modifica columnas. Aquí cubrimos sus variantes más útiles.
if_else() — Condición binariaCrea una nueva variable con dos posibles valores según una condición. Es como un SI() de Excel:
# Crear flag de alto desempeño
datos |>
mutate(
alto_desempeno = if_else(evaluacion_desempeno >= 4, "Alto", "No alto")
)
| Argumento | Qué es | Ejemplo |
|---|---|---|
| 1° — condición | Una expresión lógica (TRUE/FALSE) | evaluacion_desempeno >= 4 |
| 2° — valor si TRUE | Qué asignar cuando la condición se cumple | "Alto" |
| 3° — valor si FALSE | Qué asignar cuando no se cumple | "No alto" |
if_else() o ifelse()?
R tiene dos funciones: ifelse() (base R) e if_else() (dplyr). La de dplyr es más estricta: exige que ambos valores sean del mismo tipo (ambos texto, ambos número, etc.), lo que ayuda a prevenir errores. Usaremos siempre if_else() del tidyverse.
case_when() — Múltiples condicionesCuando necesitas más de dos opciones, case_when() es tu herramienta. Es como un SI anidado de Excel, pero legible:
# Crear tramos de antigüedad
datos |>
mutate(
tramo_antiguedad = case_when(
antiguedad_anios < 1 ~ "Menos de 1 año",
antiguedad_anios < 3 ~ "1 a 3 años",
antiguedad_anios < 5 ~ "3 a 5 años",
antiguedad_anios < 10 ~ "5 a 10 años",
TRUE ~ "10 o más años" # ← caso por defecto
)
)
La sintaxis es condición ~ valor_a_asignar. R evalúa las condiciones de arriba hacia abajo y asigna la primera que sea verdadera. TRUE ~ al final atrapa todo lo que no matcheó antes (como un "else").
< 1) ya es TRUE, así que obtiene "Menos de 1 año" y las siguientes no se evalúan. Si pusieras < 10 primero, todos los de menos de 10 caerían ahí.
# Ejemplo más complejo: clasificar tipo de rotación
datos |>
mutate(
tipo_rotacion = case_when(
rotacion == "No" ~ "Activo",
tipo_salida == "Involuntaria" ~ "Involuntaria",
tipo_salida == "Voluntaria" & alto_desempeno == "Alto" ~ "Vol. disfuncional",
tipo_salida == "Voluntaria" & alto_desempeno != "Alto" ~ "Vol. funcional"
)
)
case_when() con =case_when(
edad < 30 = "Joven" # ERROR
)
Usa = en vez de ~
case_when() con ~case_when(
edad < 30 ~ "Joven" # CORRECTO
)
La tilde ~ es el asignador de case_when()
arrange() y slice_*() — Ordenar y extraerarrange() — Ordenar filas# Ordenar por edad (ascendente, por defecto)
datos |> arrange(edad)
# Ordenar por ingreso (descendente)
datos |> arrange(desc(ingreso_mensual))
# Ordenar por dos variables: primero departamento, luego ingreso descendente
datos |> arrange(departamento, desc(ingreso_mensual))
slice_max() y slice_min() — Los N más altos/bajos# Los 5 empleados con mayor ingreso
datos |>
slice_max(ingreso_mensual, n = 5)
# Los 3 con menor satisfacción
datos |>
slice_min(satisfaccion_laboral, n = 3)
# Top 3 por departamento (combinado con group_by)
datos |>
group_by(departamento) |>
slice_max(ingreso_mensual, n = 3)
arrange() + head() o slice_max()?
Ambos pueden dar el mismo resultado, pero slice_max() es más directo y funciona con group_by() (te da el top N dentro de cada grupo). Prefiere slice_max() cuando quieres un ranking.
slice_*()| Función | Qué hace | Ejemplo |
|---|---|---|
slice_head(n = 5) | Las primeras N filas | Equivale a head(5) |
slice_tail(n = 5) | Las últimas N filas | Equivale a tail(5) |
slice_sample(n = 10) | N filas al azar | Muestra aleatoria rápida |
slice_max(x, n = 5) | Las N filas con mayor valor de x | Top 5 ingresos |
slice_min(x, n = 5) | Las N filas con menor valor de x | Bottom 5 satisfacción |
rename() y relocate() — Renombrar y reordenar columnas# Renombrar columnas (nuevo_nombre = nombre_actual)
datos |>
rename(
sueldo = ingreso_mensual,
depto = departamento
)
# Mover columnas al principio
datos |>
relocate(rotacion, tipo_salida, .before = edad)
# Mover columnas al final
datos |>
relocate(id_empleado, nombre, .after = last_col())
distinct() — Valores únicos# ¿Cuántos departamentos distintos hay?
datos |>
distinct(departamento)
# Combinaciones únicas de departamento y nivel jerárquico
datos |>
distinct(departamento, nivel_jerarquico)
# Obtener una fila por empleado (eliminar duplicados si los hay)
datos |>
distinct(id_empleado, .keep_all = TRUE)
# .keep_all = TRUE conserva todas las columnas, no solo la clave
pull() — Extraer una columna como vectorselect() devuelve un tibble (tabla). A veces necesitas un vector (un solo valor o lista de valores). Para eso existe pull():
# Esto devuelve un tibble de 1 columna:
datos |> select(edad)
# Esto devuelve un vector numérico:
datos |> pull(edad)
# Útil para extraer un valor calculado
tasa <- datos |>
summarise(tasa_rot = mean(rotacion == "Sí")) |>
pull(tasa_rot)
# Ahora 'tasa' es un número (0.272), no una tabla
paste0("La tasa de rotación es ", scales::percent(tasa))
across() — Aplicar una función a múltiples columnasCuando necesitas calcular lo mismo para varias columnas a la vez, across() evita repetir código:
# Promedio de edad, antigüedad e ingreso por departamento
datos |>
group_by(departamento) |>
summarise(
across(
c(edad, antiguedad_anios, ingreso_mensual), # columnas
mean # función
)
)
# También puedes usar selectores:
datos |>
group_by(departamento) |>
summarise(
across(where(is.numeric), mean)
# Aplica mean() a TODAS las columnas numéricas
)
# Con función personalizada (redondear a 1 decimal)
datos |>
group_by(departamento) |>
summarise(
across(where(is.numeric), \(x) round(mean(x), 1))
)
n_distinct() — Contar valores únicos# ¿Cuántos cargos distintos hay por departamento?
datos |>
group_by(departamento) |>
summarise(
n_empleados = n(),
n_cargos = n_distinct(cargo),
n_oficinas = n_distinct(oficina)
)
| Quiero... | Función | Apunte |
|---|---|---|
| Contar filas por grupo | count() | Apunte 1 |
| Filtrar filas por condición | filter() | Apunte 1 |
| Agrupar y calcular resúmenes | group_by() + summarise() | Apunte 1 |
| Elegir columnas | select() | Apunte 1 |
| Crear/modificar columnas | mutate() | Apuntes 1 y 5 |
| Condición binaria → nueva variable | if_else() | Apunte 5 |
| Múltiples condiciones → nueva variable | case_when() | Apunte 5 |
| Ordenar filas | arrange() | Apuntes 1 y 5 |
| Top N por valor | slice_max() / slice_min() | Apunte 5 |
| Renombrar columnas | rename() | Apunte 5 |
| Reordenar columnas | relocate() | Apunte 5 |
| Valores únicos | distinct() | Apunte 5 |
| Extraer vector de un tibble | pull() | Apunte 5 |
| Aplicar función a muchas columnas | across() | Apunte 5 |
| Contar valores únicos | n_distinct() | Apunte 5 |
| Unir tablas por clave | left_join() y familia | Apunte 4 |