broom y gráficos de coeficientesAnalítica de Personas · Semestre otoño 2026 · Semana 5 · Prof. René Gempp
Una interacción aparece cuando el efecto de una variable sobre Y depende del valor de otra variable. En lenguaje cotidiano: "depende".
Ejemplos en RRHH:
Sin interacción, el modelo asume que el efecto de cada variable es uniforme en toda la muestra. Con interacción, le permitimos al efecto variar según los valores de otra variable.
* y :R distingue entre dos operadores en las fórmulas:
| Sintaxis | Qué incluye |
|---|---|
A * B | Efectos principales (A y B) + interacción (A:B) |
A:B | Solo el término de interacción (sin efectos principales) |
A + B + A:B | Equivalente a A * B |
A * B, no A:B. Incluir una interacción sin sus efectos principales es matemáticamente posible pero rara vez interpretable. La excepción son los modelos con variables centradas o estandarizadas.
# Modelo con interacción genero × nivel_jerarquico
modelo_3 <- lm(
log(ingreso_mensual) ~ genero * nivel_jerarquico + departamento +
antiguedad_anios + edad + nivel_educacion +
evaluacion_desempeno,
data = empleados
)
summary(modelo_3)
Cuando agregas genero * nivel_jerarquico, R crea automáticamente:
generoMujergeneroMujer:nivel_jerarquicoOperativo, generoMujer:nivel_jerarquicoProfesional, generoMujer:nivel_jerarquicoJefaturageneroMujer ahora representa el efecto de ser mujer en la categoría de referencia de nivel jerárquico (típicamente Gerencia, por orden alfabético). Los términos de interacción son ajustes a ese efecto en cada uno de los otros niveles.
Ejemplo numérico (cifras hipotéticas):
| Término | Coeficiente | Interpretación |
|---|---|---|
generoMujer | −0.15 | Las mujeres en Gerencia ganan ≈15% menos que los hombres en Gerencia |
generoMujer:Profesional | +0.07 | En Profesional, la brecha es 7 puntos porcentuales menor que en Gerencia → ≈ −15% + 7% = −8% |
generoMujer:Operativo | +0.10 | En Operativo, la brecha es 10 pp menor → ≈ −5% |
generoMujer:Jefatura | +0.11 | En Jefatura, ≈ −4% |
Si ninguna de las interacciones es estadísticamente significativa, podemos concluir que la brecha es razonablemente uniforme entre niveles. Si alguna lo es, debemos reportar la brecha por subgrupo.
broom: tres funciones que cambian todoEl output de summary(modelo) es informativo para leer en consola, pero no se puede manipular ni graficar directamente. broom convierte los resultados de un modelo en tibbles ordenados (en el sentido de Wickham, 2014, "tidy data") que se integran con dplyr y ggplot2.
| Función | Qué devuelve | Cuándo usarla |
|---|---|---|
tidy(modelo) | Una fila por coeficiente, con estimate, std.error, statistic, p.value | Para tablas y gráficos de coeficientes |
glance(modelo) | Una sola fila con R², R² ajustado, AIC, BIC, F, df, sigma, nobs | Para comparar modelos |
augment(modelo) | Los datos originales más columnas con .fitted, .resid, .hat, .cooksd | Para diagnóstico (Apunte 12) |
tidy() con intervalos de confianzatidy(modelo_2, conf.int = TRUE)
Esto entrega un tibble con las columnas: term, estimate, std.error, statistic, p.value, conf.low, conf.high. Y esa estructura ordenada es lo que nos permite filtrar, ordenar y graficar:
# Solo el coeficiente de género
tidy(modelo_2, conf.int = TRUE) |>
filter(term == "generoMujer")
# Solo coeficientes significativos al 1%
tidy(modelo_2, conf.int = TRUE) |>
filter(p.value < 0.01)
glance() para comparar modelosbind_rows(
glance(modelo_1) |> mutate(modelo = "1: bruto"),
glance(modelo_2) |> mutate(modelo = "2: ajustado"),
glance(modelo_3) |> mutate(modelo = "3: con interacción")
) |>
select(modelo, r.squared, adj.r.squared, AIC, nobs)
Una tabla de regresión con 15 coeficientes es intimidante para un directorio. Un gráfico de coeficientes es claro, honesto y memorable. Es la visualización estándar de los economistas y se construye con geom_pointrange().
# Paso 1: extraer coeficientes ordenados
coef_tbl <- tidy(modelo_2, conf.int = TRUE) |>
filter(term != "(Intercept)") |>
mutate(
significativo = p.value < 0.05,
term = fct_reorder(term, estimate)
)
# Paso 2: graficar con geom_pointrange()
ggplot(coef_tbl, aes(x = estimate, y = term, color = significativo)) +
geom_vline(xintercept = 0, linetype = "dashed") +
geom_pointrange(aes(xmin = conf.low, xmax = conf.high)) +
scale_color_manual(values = c("TRUE" = "#B85042", "FALSE" = "#A7BEAE")) +
labs(
title = "Coeficientes del modelo de equidad salarial",
subtitle = "VD = log(ingreso). Punto = estimado; barra = IC 95%.",
x = "Coeficiente (≈ % de cambio en el salario)",
y = NULL
) +
theme_minimal() +
theme(legend.position = "bottom")
predict()Una pregunta natural en una auditoría: "¿cuánto ganaría esta misma persona si fuera del otro género, manteniendo todo lo demás constante?". Es exactamente para eso que sirve predict().
# Tomar un caso real de la base
caso_real <- empleados |>
filter(genero == "Mujer", nivel_jerarquico == "Profesional") |>
slice(1)
# Crear su versión contrafactual: misma persona, género cambiado
caso_cf <- caso_real |> mutate(genero = "Hombre")
# Predecir con ambos casos (escala log)
pred_real <- predict(modelo_2, newdata = caso_real)
pred_cf <- predict(modelo_2, newdata = caso_cf)
# Volver a la escala original (pesos chilenos)
exp(pred_real)
exp(pred_cf)
exp(pred_cf) - exp(pred_real)
exp():
Si tu VD es log(salario), lo que predict() devuelve son log-salarios predichos. Para volverlos a pesos chilenos, hay que aplicar la función inversa del logaritmo, que es la exponencial: exp(). Esto se conoce como "des-transformar" o "back-transform".
| Tarea | Función | Apunte |
|---|---|---|
| Ajustar modelo lineal | lm(VD ~ VI, data) | 11 |
| Lectura del modelo | summary(modelo) | 11 |
| Coeficientes ordenados | broom::tidy(modelo, conf.int = TRUE) | 13 |
| Métricas globales | broom::glance(modelo) | 13 |
| Residuos y diagnóstico | broom::augment(modelo) | 12 |
| Multicolinealidad | car::vif(modelo) | 12 |
| Interacciones | VI1 * VI2 en la fórmula | 13 |
| Comparar modelos anidados | anova(m1, m2) | 13 |
| Predicción contrafactual | predict(modelo, newdata = ...) | 13 |
| Gráfico de coeficientes | geom_pointrange() | 13 |