1 1. Introducción del problema

El objetivo de esta actividad es construir un modelo que permita comprender las razones por las cuales los empleados deciden cambiar de cargo y, al mismo tiempo, estimar la probabilidad de que dicha rotación ocurra. Para ello, se utilizará la técnica estadística de regresión logística, adecuada para predecir resultados binarios. En este caso, la variable de interés será la rotación de cargo, codificada en dos categorías: sí rota y no rota.

2 2. Preparación del entorno y carga de datos

Inicialmente, se prepara el espacio de trabajo. Esto implica instalar y cargar los paquetes que permiten llevar a cabo la actividad.


# Instalar el paquete de datos

devtools::install_github("centromagis/paqueteMODELOS", force = TRUE)
## 
## ── R CMD build ─────────────────────────────────────────────────────────────────
##       ✔  checking for file 'C:\Users\angel\AppData\Local\Temp\Rtmpg3Apg8\remotesae846051da7\Centromagis-paqueteMODELOS-3b06257/DESCRIPTION'
##       ─  preparing 'paqueteMODELOS':
##    checking DESCRIPTION meta-information ...  ✔  checking DESCRIPTION meta-information
##       ─  checking for LF line-endings in source and make files and shell scripts
##   ─  checking for empty or unneeded directories
##       ─  building 'paqueteMODELOS_0.1.0.tar.gz'
##      
## 

A continuación se presenta una primera visualización de la estructura del conjunto de datos, donde se observa que contiene 1.470 registros y 24 variables:

# Cargar y explorar los datos
data("rotacion")
glimpse(rotacion, 80)
## Rows: 1,470
## Columns: 24
## $ Rotación                    <chr> "Si", "No", "Si", "No", "No", "No", "No", …
## $ Edad                        <dbl> 41, 49, 37, 33, 27, 32, 59, 30, 38, 36, 35…
## $ `Viaje de Negocios`         <chr> "Raramente", "Frecuentemente", "Raramente"…
## $ Departamento                <chr> "Ventas", "IyD", "IyD", "IyD", "IyD", "IyD…
## $ Distancia_Casa              <dbl> 1, 8, 2, 3, 2, 2, 3, 24, 23, 27, 16, 15, 2…
## $ Educación                   <dbl> 2, 1, 2, 4, 1, 2, 3, 1, 3, 3, 3, 2, 1, 2, …
## $ Campo_Educación             <chr> "Ciencias", "Ciencias", "Otra", "Ciencias"…
## $ Satisfacción_Ambiental      <dbl> 2, 3, 4, 4, 1, 4, 3, 4, 4, 3, 1, 4, 1, 2, …
## $ Genero                      <chr> "F", "M", "M", "F", "M", "M", "F", "M", "M…
## $ Cargo                       <chr> "Ejecutivo_Ventas", "Investigador_Cientifi…
## $ Satisfación_Laboral         <dbl> 4, 2, 3, 3, 2, 4, 1, 3, 3, 3, 2, 3, 3, 4, …
## $ Estado_Civil                <chr> "Soltero", "Casado", "Soltero", "Casado", …
## $ Ingreso_Mensual             <dbl> 5993, 5130, 2090, 2909, 3468, 3068, 2670, …
## $ Trabajos_Anteriores         <dbl> 8, 1, 6, 1, 9, 0, 4, 1, 0, 6, 0, 0, 1, 0, …
## $ Horas_Extra                 <chr> "Si", "No", "Si", "Si", "No", "No", "Si", …
## $ Porcentaje_aumento_salarial <dbl> 11, 23, 15, 11, 12, 13, 20, 22, 21, 13, 13…
## $ Rendimiento_Laboral         <dbl> 3, 4, 3, 3, 3, 3, 4, 4, 4, 3, 3, 3, 3, 3, …
## $ Años_Experiencia            <dbl> 8, 10, 7, 8, 6, 8, 12, 1, 10, 17, 6, 10, 5…
## $ Capacitaciones              <dbl> 0, 3, 3, 3, 3, 2, 3, 2, 2, 3, 5, 3, 1, 2, …
## $ Equilibrio_Trabajo_Vida     <dbl> 1, 3, 3, 3, 3, 2, 2, 3, 3, 2, 3, 3, 2, 3, …
## $ Antigüedad                  <dbl> 6, 10, 0, 8, 2, 7, 1, 1, 9, 7, 5, 9, 5, 2,…
## $ Antigüedad_Cargo            <dbl> 4, 7, 0, 7, 2, 7, 0, 0, 7, 7, 4, 5, 2, 2, …
## $ Años_ultima_promoción       <dbl> 0, 1, 0, 3, 2, 3, 0, 0, 1, 7, 0, 0, 4, 1, …
## $ Años_acargo_con_mismo_jefe  <dbl> 5, 7, 0, 0, 2, 6, 0, 0, 8, 7, 3, 8, 3, 2, …
#Organizar para entender con facilidad
variables <- data.frame(
  Variable = c("Rotación", "Edad", "Viaje de Negocios", "Departamento", 
               "Distancia_Casa", "Educación", "Campo_Educación", 
               "Satisfacción_Ambiental", "Género", "Cargo", 
               "Satisfacción_Laboral", "Estado_Civil", "Ingreso_Mensual", 
               "Trabajos_Anteriores", "Horas_Extra", "Porcentaje_Aumento_Salarial", 
               "Rendimiento_Laboral", "Años_Experiencia", "Capacitaciones", 
               "Equilibrio_Trabajo_Vida", "Antigüedad", "Antigüedad_Cargo", 
               "Años_Última_Promoción", "Años_Acargo_Con_Mismo_Jefe"),
  
  Tipo = c("Categórica (dicotómica, variable respuesta)", 
           "Cuantitativa (numérica continua)", 
           "Categórica (ordinal: Raramente, Frecuentemente, Nunca)", 
           "Categórica (nominal)", 
           "Cuantitativa (numérica discreta, km)", 
           "Categórica ordinal (1–5, nivel educativo)", 
           "Categórica (nominal)", 
           "Categórica ordinal (1–4)", 
           "Categórica (nominal: M/F)", 
           "Categórica (nominal)", 
           "Categórica ordinal (1–4)", 
           "Categórica (nominal)", 
           "Cuantitativa (numérica continua, $)", 
           "Cuantitativa (numérica discreta)", 
           "Categórica dicotómica (Sí/No)", 
           "Cuantitativa (porcentaje)", 
           "Categórica ordinal (1–4)", 
           "Cuantitativa (numérica continua)", 
           "Cuantitativa (numérica discreta)", 
           "Categórica ordinal (1–4)", 
           "Cuantitativa (años en la empresa)", 
           "Cuantitativa (años en el cargo)", 
           "Cuantitativa (años desde la última promoción)", 
           "Cuantitativa (años con el mismo jefe)"))

kable(variables, caption = "Clasificación de las variables de la base de datos Rotación")
Clasificación de las variables de la base de datos Rotación
Variable Tipo
Rotación Categórica (dicotómica, variable respuesta)
Edad Cuantitativa (numérica continua)
Viaje de Negocios Categórica (ordinal: Raramente, Frecuentemente, Nunca)
Departamento Categórica (nominal)
Distancia_Casa Cuantitativa (numérica discreta, km)
Educación Categórica ordinal (1–5, nivel educativo)
Campo_Educación Categórica (nominal)
Satisfacción_Ambiental Categórica ordinal (1–4)
Género Categórica (nominal: M/F)
Cargo Categórica (nominal)
Satisfacción_Laboral Categórica ordinal (1–4)
Estado_Civil Categórica (nominal)
Ingreso_Mensual Cuantitativa (numérica continua, $)
Trabajos_Anteriores Cuantitativa (numérica discreta)
Horas_Extra Categórica dicotómica (Sí/No)
Porcentaje_Aumento_Salarial Cuantitativa (porcentaje)
Rendimiento_Laboral Categórica ordinal (1–4)
Años_Experiencia Cuantitativa (numérica continua)
Capacitaciones Cuantitativa (numérica discreta)
Equilibrio_Trabajo_Vida Categórica ordinal (1–4)
Antigüedad Cuantitativa (años en la empresa)
Antigüedad_Cargo Cuantitativa (años en el cargo)
Años_Última_Promoción Cuantitativa (años desde la última promoción)
Años_Acargo_Con_Mismo_Jefe Cuantitativa (años con el mismo jefe)

La clasificación de variables permite identificar con claridad la variable respuesta (Rotación), distinguir entre las predictoras numéricas y las categóricas, y precisar que algunas variables ordinales (como Educación, Satisfacción Laboral y Rendimiento Laboral) pueden ser tratadas como cuantitativas discretas dentro del modelo logístico, con el fin de facilitar su inclusión en el análisis y la interpretación de resultados.

2.1 2.1 Limpieza Base de Datos

# estandariza nombres
rotacion <- rotacion %>% clean_names()

# Conteo de NA por variable
na_por_variable <- sapply(rotacion, function(x) sum(is.na(x)))
na_por_variable <- sort(na_por_variable, decreasing = TRUE)

na_tabla <- data.frame(
  variable = names(na_por_variable),
  na_conteo = as.integer(na_por_variable),
  na_porcentaje = round(100 * na_por_variable / nrow(rotacion), 2)
)

kable(na_tabla, caption = "Número y porcentaje de valores faltantes por variable")
Número y porcentaje de valores faltantes por variable
variable na_conteo na_porcentaje
rotacion rotacion 0 0
edad edad 0 0
viaje_de_negocios viaje_de_negocios 0 0
departamento departamento 0 0
distancia_casa distancia_casa 0 0
educacion educacion 0 0
campo_educacion campo_educacion 0 0
satisfaccion_ambiental satisfaccion_ambiental 0 0
genero genero 0 0
cargo cargo 0 0
satisfacion_laboral satisfacion_laboral 0 0
estado_civil estado_civil 0 0
ingreso_mensual ingreso_mensual 0 0
trabajos_anteriores trabajos_anteriores 0 0
horas_extra horas_extra 0 0
porcentaje_aumento_salarial porcentaje_aumento_salarial 0 0
rendimiento_laboral rendimiento_laboral 0 0
anos_experiencia anos_experiencia 0 0
capacitaciones capacitaciones 0 0
equilibrio_trabajo_vida equilibrio_trabajo_vida 0 0
antiguedad antiguedad 0 0
antiguedad_cargo antiguedad_cargo 0 0
anos_ultima_promocion anos_ultima_promocion 0 0
anos_acargo_con_mismo_jefe anos_acargo_con_mismo_jefe 0 0

La base de datos no muestra datos faltantes.

# Duplicados en la base imputada
duplicados <- rotacion[duplicated(rotacion), ]
cat("Número de registros duplicados:", nrow(duplicados), "\n")
## Número de registros duplicados: 0

La base de datos no muestra registros duplicados.

3 3. Selección de variables e hipótesis

Dentro de la selección de las 3 variables cuantitativas y 3 variables cualitativas, que permitan influir en la decisión de un empleado a rotar, plantearemos las siguientes

3.1 3.1 Preprocesamiento de la variable respuesta

Con el fin de preparar la variable de respuesta para la estimación del modelo logístico, se realizó un proceso de codificación binaria. En este paso, la variable Rotación fue normalizada para garantizar uniformidad en sus valores (“Sí” / “No”), y posteriormente se creó una nueva columna denominada rotacion_num, donde “Sí” corresponde a 1 y “No” a 0.

# Normalizar valores de la variable rotacion y crear binaria
rotacion <- rotacion %>%
  mutate(
    rotacion = str_to_title(str_squish(rotacion)),   # "Si" / "No"
    rotacion_num = if_else(rotacion == "Si", 1L, 0L)
  )

# Verificación presentable
tab <- table("Rotación" = rotacion$rotacion,
             "Rotacion_num" = rotacion$rotacion_num)

kable(as.data.frame.matrix(tab),
      caption = "Matriz de homologación de la variable Rotación")
Matriz de homologación de la variable Rotación
0 1
No 1233 0
Si 0 237

La Matriz de homologación de la variable Rotación confirma que la conversión se ejecutó correctamente: los 1.233 casos sin rotación fueron codificados como 0 y los 237 casos con rotación fueron codificados como 1. De esta manera, se asegura la compatibilidad de la variable respuesta con la regresión logística y se mantiene la integridad de la información original.

3.2 3.2 Definición de variables cuantitativas

  1. Ingreso mensual (ingreso_mensual)

    • Justificación: El salario es uno de los principales factores de satisfacción dentro del ámbito laboral. Un ingreso bajo puede ser un motivador para buscar otras oportunidades.
    • Hipótesis: Se espera una relación negativa. A mayor ingreso mensual, menor será la probabilidad de que un empleado rote.
  2. Antigüedad en el cargo (antiguedad_cargo)

    • Justificación: Un empleado con mucho tiempo en el mismo cargo, sin ascensos ni nuevos desafíos, puede sentirse desmotivado y buscar un cambio.
    • Hipótesis: Se espera una relación positiva. A mayor antigüedad, mayor será la probabilidad de rotación.
  3. Satisfacción laboral (satisfaccion_laboral)

    • Justificación: Esta variable mide el nivel de satisfacción del empleado con su trabajo, siendo un factor determinante de permanencia o búsqueda de cambio.
    • Hipótesis: Se espera una relación negativa. A mayor satisfacción laboral, menor será la probabilidad de rotación.

Notas:

Aunque la variable Satisfacción Laboral está definida en una escala ordinal de 1 a 4, en este análisis se la considera como cuantitativa. Esta decisión se justifica porque los valores reflejan un orden natural de menor a mayor satisfacción y se asume que los incrementos entre categorías son comparables.

La variable Antigüedad en el Cargo corresponde a una medida de tiempo expresada en años completos. Al ser un conteo de unidades, se clasifica como variable cuantitativa discreta, pues toma valores numéricos enteros y permite analizar cómo la permanencia en el puesto se relaciona con la probabilidad de rotación.


3.3 3.3 Definición de variables categóricas

  1. Horas extra (horas_extra)
    • Justificación: Trabajar horas de manera constante puede generar agotamiento y afectar el equilibrio entre la vida laboral y personal, llevando al empleado a buscar un trabajo más manejable.
    • Hipótesis: Se espera que los empleados que trabajan horas extra tengan una mayor probabilidad de rotar frente a quienes no lo hacen.
  2. Estado civil (estado_civil)
    • Justificación: El estado civil puede influir en la estabilidad percibida. Una persona casada podría valorar más la estabilidad que una soltera, quien tendría mayor flexibilidad para cambiar de empleo o de ciudad.
    • Hipótesis: Se espera que los empleados solteros presenten mayor probabilidad de rotación en comparación con casados y divorciados.
  3. Viaje de negocios (viaje_de_negocios)
    • Justificación: La frecuencia de viajes de negocios puede generar estrés y afectar la vida laboral y personal del empleado.
    • Hipótesis: Se espera que los empleados que viajan frecuentemente tengan una mayor probabilidad de rotar que aquellos que viajan rara vez o no viajan.

Notas:

Estas variables son relevantes porque reflejan factores de carga laboral, estabilidad personal y balance vida-trabajo, los cuales la literatura sugiere que están asociados con la decisión de permanecer o salir de la organización. Aunque Horas Extra, Estado Civil y Viaje de Negocios son cualitativas, se pueden incluir en un modelo estadístico (p. ej. regresión logística) mediante codificación dummy.

 variables <- data.frame(
  Variable = c("Ingreso mensual", "Antigüedad en el cargo", "Satisfacción laboral",
               "Horas extra", "Estado civil", "Viaje de negocios"),
  Tipo = c("Cuantitativa continua", "Cuantitativa discreta (años).", "Escala ordinal (1–4), tratada como cuantitativa discreta.",
           "Categórica dicotómica (Sí/No)", "Categórica nominal (Casado, Soltero, Divorciado)", "Categórica ordinal (Raramente, Frecuentemente, Nunca)"),
  Justificacion = c(
    "Factor clave de satisfacción laboral; ingresos bajos motivan a buscar nuevas oportunidades",
    "Una permanencia prolongada sin ascensos puede generar desmotivación.",
    "Nivel de satisfacción con el trabajo, asociado a permanencia o búsqueda de cambio.",
    "Carga laboral adicional que puede generar agotamiento y afectar la vida personal.",
    "Situación personal que puede influir en la percepción de estabilidad y flexibilidad.",
    "La frecuencia de viajes puede generar estrés y afectar el equilibrio personal."
  ),
  Hipotesis = c(
    "Negativa: a mayor ingreso, menor probabilidad de rotación.",
    "Positiva: a mayor antigüedad, mayor probabilidad de rotación.",
    "Negativa: a mayor satisfacción, menor probabilidad de rotación.",
    "Los empleados que trabajan horas extra tienen mayor probabilidad de rotar frente a quienes no lo hacen.",
    "Solteros presentan mayor probabilidad de rotación que casados o divorciados.",
    "Frecuentes más propensos a rotar que quienes viajan rara vez o nunca."
  )
)

kable(variables, caption = "Resumen de variables seleccionadas")  
Resumen de variables seleccionadas
Variable Tipo Justificacion Hipotesis
Ingreso mensual Cuantitativa continua Factor clave de satisfacción laboral; ingresos bajos motivan a buscar nuevas oportunidades Negativa: a mayor ingreso, menor probabilidad de rotación.
Antigüedad en el cargo Cuantitativa discreta (años). Una permanencia prolongada sin ascensos puede generar desmotivación. Positiva: a mayor antigüedad, mayor probabilidad de rotación.
Satisfacción laboral Escala ordinal (1–4), tratada como cuantitativa discreta. Nivel de satisfacción con el trabajo, asociado a permanencia o búsqueda de cambio. Negativa: a mayor satisfacción, menor probabilidad de rotación.
Horas extra Categórica dicotómica (Sí/No) Carga laboral adicional que puede generar agotamiento y afectar la vida personal. Los empleados que trabajan horas extra tienen mayor probabilidad de rotar frente a quienes no lo hacen.
Estado civil Categórica nominal (Casado, Soltero, Divorciado) Situación personal que puede influir en la percepción de estabilidad y flexibilidad. Solteros presentan mayor probabilidad de rotación que casados o divorciados.
Viaje de negocios Categórica ordinal (Raramente, Frecuentemente, Nunca) La frecuencia de viajes puede generar estrés y afectar el equilibrio personal. Frecuentes más propensos a rotar que quienes viajan rara vez o nunca.

4 4. Análisis univariado

En esta sección se realiza un análisis univariado, cuyo propósito es examinar cada variable de manera individual para comprender su distribución, características principales y posibles patrones. Este paso permite identificar tendencias generales en los datos y constituye la base para explorar relaciones más complejas en las etapas posteriores del análisis.

# Tabla de frecuencias
tabla_rotacion <- table(rotacion$rotacion)
cat("Frecuencia de Rotación de Empleados\n")
## Frecuencia de Rotación de Empleados
print(tabla_rotacion)
## 
##   No   Si 
## 1233  237
# Tabla de proporciones
prop_rotacion <- prop.table(tabla_rotacion) * 100
cat("Proporciones de Rotación de Empleados (%)\n")
## Proporciones de Rotación de Empleados (%)
print(round(prop_rotacion, 2))
## 
##    No    Si 
## 83.88 16.12
# Gráfico de barras con porcentajes
ggplot(rotacion, aes(x = rotacion, fill = rotacion)) +
  geom_bar() +
  geom_text(stat = "count", aes(label = paste0(round(..count../sum(..count..) * 100,1), "%")),
            vjust = -0.5) +
  scale_fill_brewer(palette = "Set2") +
  labs(title = "Distribución de la variable Rotación",
       x = "Rotación", y = "Número de empleados") +
  theme_minimal()

La variable Rotación presenta un comportamiento claramente desbalanceado. Del total de 1.470 empleados, 1.233 (83,9%) no cambiaron de cargo, mientras que únicamente 237 (16,1%) sí realizaron un cambio. Esta distribución indica que la mayoría de los empleados tienden a permanecer en sus puestos, y solo una fracción menor experimenta rotación.

Es importante tener en cuenta este desbalance en la variable de respuesta al momento de ajustar el modelo logístico, ya que puede influir en la capacidad predictiva y en la interpretación de los resultados.

4.1 4.1 Variables cuantitativas

# Resumen estadístico de las variables cuantitativas

summary(rotacion[, c("ingreso_mensual", "antiguedad_cargo", "satisfacion_laboral")])
##  ingreso_mensual antiguedad_cargo satisfacion_laboral
##  Min.   : 1009   Min.   : 0.000   Min.   :1.000      
##  1st Qu.: 2911   1st Qu.: 2.000   1st Qu.:2.000      
##  Median : 4919   Median : 3.000   Median :3.000      
##  Mean   : 6503   Mean   : 4.229   Mean   :2.729      
##  3rd Qu.: 8379   3rd Qu.: 7.000   3rd Qu.:4.000      
##  Max.   :19999   Max.   :18.000   Max.   :4.000
# Histograma del Ingreso Mensual

ggplot(rotacion, aes(x = ingreso_mensual)) +
  geom_histogram(binwidth = 1000, fill = "blue", color = "white") +
  labs(title = "Distribución del Ingreso Mensual", x = "Ingreso ($)", y = "Frecuencia")

# Histograma de la Antigüedad en el Cargo

ggplot(rotacion, aes(x = antiguedad_cargo)) +
  geom_histogram(binwidth = 1, fill = "green", color = "white") +
  labs(title = "Distribución de la Antigüedad en el Cargo", x = "Años en el cargo", y = "Frecuencia")

# Histograma de Satisfacción Laboral
ggplot(rotacion, aes(x = satisfacion_laboral)) +
  geom_histogram(binwidth = 1, fill = "purple", color = "white") +
  labs(title = "Distribución de la Satisfacción Laboral", 
       x = "Nivel de satisfacción (1=Muy baja, 4=Muy alta)", 
       y = "Frecuencia")

Interpretración:

  • Ingreso Mensual: El análisis univariado muestra que el ingreso tiene una distribución sesgada a la derecha, con la mayoría de empleados concentrados en niveles bajos y medios (mediana ≈ 4.9 mil). Esto confirma que gran parte de la fuerza laboral percibe salarios relativamente modestos, lo cual puede ser un factor de presión para buscar nuevas oportunidades. La hipótesis planteada de que un menor ingreso mensual aumenta la probabilidad de rotación se fundamenta en esta concentración en los rangos bajos.
  • Antiguedad en el Cargo: Se observa que la mediana de antigüedad es de 3 años, con pocos empleados que superan los 10 años en el mismo cargo. Esta distribución sesgada indica que la permanencia prolongada en un mismo puesto es poco común. Esto respalda la hipótesis de que una mayor antigüedad en el cargo incrementa la probabilidad de rotación, ya que los empleados que llevan más tiempo podrían buscar movilidad interna o externa ante la falta de cambios.
  • Satisfacción Laboral: La variable, medida en escala de 1 a 4, muestra mayor concentración en niveles medios y altos (3 y 4), aunque con presencia relevante de valores bajos. Esto significa que, si bien muchos empleados están satisfechos, existe un grupo no despreciable con niveles reducidos de satisfacción. Esta evidencia justifica su inclusión, pues permite contrastar si niveles bajos de satisfacción laboral se asocian con una mayor probabilidad de rotación, como se planteó en la hipótesis inicial.

4.2 4.2 Variables categóricas

# Tabla de frecuencias para Horas Extra
cat("Frecuencia de empleados por Horas Extra\n")
## Frecuencia de empleados por Horas Extra
table(rotacion$horas_extra)
## 
##   No   Si 
## 1054  416
# Tabla de frecuencias para Estado Civil
cat("\nFrecuencia de empleados por Estado Civil\n")
## 
## Frecuencia de empleados por Estado Civil
table(rotacion$estado_civil)
## 
##     Casado Divorciado    Soltero 
##        673        327        470
# Tabla de frecuencias para Viaje de Negocios
cat("\nFrecuencia de empleados por Viaje de Negocios\n")
## 
## Frecuencia de empleados por Viaje de Negocios
table(rotacion$viaje_de_negocios)
## 
## Frecuentemente       No_Viaja      Raramente 
##            277            150           1043
# Gráfico para Horas Extra
ggplot(rotacion, aes(x = horas_extra, fill = horas_extra)) +
  geom_bar() +
  labs(title = "Distribución de Horas Extra", 
       x = "Horas Extra", 
       y = "Cantidad") +
  theme_minimal()

# Gráfico para Estado Civil
ggplot(rotacion, aes(x = estado_civil, fill = estado_civil)) +
  geom_bar() +
  labs(title = "Distribución por Estado Civil", 
       x = "Estado Civil", 
       y = "Cantidad") +
  theme_minimal()

# Gráfico para Viaje de Negocios
ggplot(rotacion, aes(x = viaje_de_negocios, fill = viaje_de_negocios)) +
  geom_bar() +
  labs(title = "Frecuencia de Viajes de Negocios", 
       x = "Frecuencia de viaje", 
       y = "Cantidad") +
  theme_minimal()

Interpretación:

  • Horas Extra: La mayoría de los empleados no realizan horas extra (1054), frente a 416 que sí las realizan. Esto muestra un desbalance que puede ser importante, ya que quienes hacen horas extra podrían estar más expuestos al agotamiento y, por ende, tener mayor probabilidad de rotación.
  • Estado Civil: La mayor proporción de empleados son casados (673), seguidos de solteros (470) y divorciados (327). Esta variable puede reflejar distintos grados de estabilidad o flexibilidad laboral. En teoría, empleados casados tenderían a priorizar estabilidad, mientras que los solteros podrían estar más abiertos a cambiar de trabajo.
  • Viaje de Negocios: Se observa que la gran mayoría viaja raramente (1043), un grupo más reducido viaja frecuentemente (277) y un grupo aún menor no viaja nunca (150). Esta variable puede incidir en el equilibrio entre vida personal y laboral: quienes viajan con mayor frecuencia podrían experimentar mayor desgaste, lo que incrementa la probabilidad de rotación.

5 5. Análisis bivariado

En esta sección se analiza la relación entre la variable respuesta Rotación y las variables predictoras seleccionadas. Para las variables cuantitativas se utilizan diagramas de caja (boxplots), que permiten comparar la distribución de los valores según los grupos de rotación (Sí/No). Para las variables categóricas se emplean gráficos de barras proporcionales, con el fin de observar la proporción de empleados que rotan en cada categoría.

Este análisis exploratorio busca identificar patrones iniciales que puedan anticipar comportamientos relevantes en el modelo de regresión.

# Ingreso Mensual vs. Rotación (Boxplot)

ggplot(rotacion, aes(x = rotacion, y = ingreso_mensual, fill = rotacion)) +
  geom_boxplot() +
  labs(title = "Ingreso Mensual según Rotación", y = "Ingreso ($)") +
  theme_minimal()

Interpretación:

Se observa que el ingreso mensual mediano y promedio de los empleados que rotaron es considerablemente menor en comparación con el de aquellos que permanecieron en la empresa. Esto indica que los salarios más bajos están asociados con una mayor probabilidad de rotación, lo cual confirma la hipótesis inicial: a mayor ingreso, menor probabilidad de rotación.

Se presentan algunos datos atípicos en el límite superior.

# Antigüedad en el Cargo vs. Rotación (Boxplot)

ggplot(rotacion, aes(x = rotacion, y = antiguedad_cargo, fill = rotacion)) +
  geom_boxplot() +
  labs(title = "Antigüedad en el Cargo según Rotación", y = "Años en el Cargo")

Interpretación: Se observa que los empleados que rotaron presentan, en promedio, una menor antigüedad en el cargo en comparación con quienes permanecieron en la empresa. Este resultado es contrario a la hipótesis inicial, que planteaba que una mayor antigüedad podía incrementar la probabilidad de rotación por desmotivación o falta de ascensos. Se presentan algunos datos atípicos en el límite superior.

# Satisfaccion laboral vs. Rotación (Boxplot)
ggplot(rotacion, aes(x = rotacion, y = satisfacion_laboral, fill = rotacion)) +
  geom_boxplot() +
  labs(title = "Satisfacción Laboral según Rotación", 
       y = "Nivel de Satisfacción (1 = Muy baja, 4 = Muy alta)") +
  theme_minimal()

Interpretación: El gráfico muestra que los empleados que no rotaron tienden a tener niveles de satisfacción laboral más altos (mediana alrededor de 3), mientras que los que sí rotaron presentan niveles de satisfacción más bajos (mediana en 2).Esto confirma la hipótesis inicial: a mayor satisfacción laboral, menor probabilidad de rotación.

# Horas Extra vs. Rotación (Gráfico de proporciones)

ggplot(rotacion, aes(x = horas_extra, fill = rotacion)) +
  geom_bar(position = "fill") +
  labs(title = "Proporción de Rotación según Horas Extra", y = "Proporción") +
  scale_y_continuous(labels = scales::percent)

Interpretación:

La gráfica muestra que la proporción de empleados que rotan es mayor entre quienes realizan horas extra, en comparación con aquellos que no las realizan.Este hallazgo confirma la hipótesis planteada: una mayor carga laboral (expresada en horas extra) incrementa la probabilidad de rotación, posiblemente porque el desequilibrio entre la vida laboral y personal genera insatisfacción y búsqueda de otras oportunidades.

# Estado Civil vs. Rotación

ggplot(rotacion, aes(x = estado_civil, fill = rotacion)) +
  geom_bar(position = "fill") +
  labs(title = "Proporción de Rotación según Estado Civil", y = "Proporción") +
  scale_y_continuous(labels = scales::percent)

Interpretación:

La gráfica muestra que los empleados solteros presentan la mayor proporción de rotación, en comparación con los casados y divorciados.Este resultado confirma la hipótesis inicial: la situación personal y familiar puede influir en la estabilidad laboral, siendo los solteros más proclives a cambiar de empleo, probablemente debido a una mayor flexibilidad para asumir riesgos o explorar nuevas oportunidades.

# Viaje de Negocios vs. Rotación (Gráfico de proporciones)

ggplot(rotacion, aes(x = viaje_de_negocios, fill = rotacion)) +
  geom_bar(position = "fill") +
  labs(title = "Proporción de Rotación según Viaje de Negocios", 
       x = "Frecuencia de Viaje", 
       y = "Proporción") +
  scale_y_continuous(labels = scales::percent) +
  theme_minimal()

Interpretación:

Se observa que los empleados que viajan frecuentemente presentan una proporción más alta de rotación en comparación con quienes no viajan o lo hacen raramente. Esto respalda la hipótesis de que los viajes de negocios frecuentes pueden generar mayor desgaste y afectar el equilibrio personal, aumentando la probabilidad de rotación. Por el contrario, los empleados que no viajan muestran la proporción más baja de rotación, lo que sugiere una mayor estabilidad laboral en este grupo.

# Variables seleccionadas
vars <- c("ingreso_mensual",
          "antiguedad_cargo",
          "satisfacion_laboral",
          "horas_extra",
          "estado_civil",
          "viaje_de_negocios")

# Funcion para ajustar cada modelo bivariado
ajusta_logit_bivariado <- function(var){
  f <- as.formula(paste("rotacion_num ~", var))
  m <- glm(f, data = rotacion, family = binomial())  # <-- base original (sin ROSE)
  broom::tidy(m, conf.int = TRUE, conf.level = 0.95, exponentiate = TRUE) %>%
    dplyr::filter(term != "(Intercept)") %>%
    dplyr::mutate(variable = var) %>%
    dplyr::select(variable, term,
                  OR = estimate, IC95_inf = conf.low, IC95_sup = conf.high,
                  p.value)
}

tabla_bivariado <- dplyr::bind_rows(lapply(vars, ajusta_logit_bivariado)) %>%
  dplyr::arrange(variable, desc(OR))

knitr::kable(tabla_bivariado, digits = 3,
             caption = "Modelos logisticos bivariados (OR, IC95% y p-valor)")
Modelos logisticos bivariados (OR, IC95% y p-valor)
variable term OR IC95_inf IC95_sup p.value
antiguedad_cargo antiguedad_cargo 0.864 0.823 0.905 0.000
estado_civil estado_civilSoltero 2.404 1.769 3.281 0.000
estado_civil estado_civilDivorciado 0.787 0.508 1.194 0.271
horas_extra horas_extraSi 3.771 2.832 5.032 0.000
ingreso_mensual ingreso_mensual 1.000 1.000 1.000 0.000
satisfacion_laboral satisfacion_laboral 0.778 0.686 0.881 0.000
viaje_de_negocios viaje_de_negociosRaramente 0.530 0.386 0.734 0.000
viaje_de_negocios viaje_de_negociosNo_Viaja 0.262 0.131 0.485 0.000

Interpretación:

Los resultados del análisis bivariado muestran que varias de las variables seleccionadas presentan una asociación estadísticamente significativa con la rotación de empleados:

Ingreso mensual (OR ≈ 1.000, p < 0.001): aunque el valor del OR parece cercano a 1, al interpretarlo en miles de pesos se confirma que mayores ingresos reducen la probabilidad de rotación. Esto coincide con la hipótesis inicial de que los salarios bajos son un factor de riesgo.

Antigüedad en el cargo (OR = 0.864, p < 0.001): por cada año adicional en el cargo, la probabilidad de rotación disminuye en un 13,6%. Este resultado contradice la hipótesis planteada inicialmente, que proponía que una permanencia prolongada podría incrementar la rotación.

Satisfacción laboral (OR = 0.778, p < 0.001): cada punto adicional en la escala de satisfacción reduce en un 22% la probabilidad de rotar, lo que confirma la hipótesis inicial.

Horas extra (OR = 3.771, p < 0.001): trabajar horas adicionales incrementa en casi 4 veces la probabilidad de rotación, mostrando un efecto altamente significativo.Confirma la hipótesis inicial.

Estado civil: los empleados solteros presentan más del doble de probabilidad de rotar que los casados (OR = 2.404, p < 0.001), mientras que los divorciados no muestran diferencias significativas (p = 0.271).Coincide en gran parte, salvo que los divorciados no muestran diferencias.

Viajes de negocios: quienes viajan frecuentemente tienen casi el doble de probabilidad de rotación frente a quienes viajan raramente (OR = 1.886, p < 0.001). En contraste, los que no viajan tienen una probabilidad significativamente menor de rotar (OR = 0.494, p = 0.025).En línea con lo esperado.

En conjunto, estos hallazgos confirman la mayoría de las hipótesis planteadas en la etapa exploratoria (ingresos, satisfacción laboral, horas extra, estado civil y viajes de negocios), aunque evidencian que la antigüedad en el cargo opera de manera inversa a lo esperado: en lugar de aumentar la probabilidad de rotación, parece favorecer la permanencia.

6 6. Estimación del modelo de regresión logística

Ahora, con las variables seleccionadas las combinaremos en un único modelo buscando predecir la rotación. Es importante que para ejecutar el modelo logístico las clases se encuentren balancedadas.

Con el análisis anterior habíamos evidenciado que la variable respuesta Rotación presentaba un desbalance, por lo cual antes de ejecutar el Modelo realizamos ese balanceo.

Adicionalmente, las variables predictoras categóricas se definen como factores con niveles ordenados y coherentes para que el modelo las use bien.

# Categóricas como factor con niveles consistentes
rotacion$horas_extra       <- factor(rotacion$horas_extra,       levels = c("No","Si"))
rotacion$estado_civil      <- factor(rotacion$estado_civil,      levels = c("Casado","Divorciado","Soltero"))
rotacion$viaje_de_negocios <- factor(rotacion$viaje_de_negocios, levels = c("Raramente","Frecuentemente","No_Viaja"))

# Balanceo de Rotacion

set.seed(123)
rotacion_balanceada <- ROSE(
  rotacion_num ~ ingreso_mensual + antiguedad_cargo +
    satisfacion_laboral + horas_extra + estado_civil + viaje_de_negocios,
  data = rotacion, seed = 123
)$data

# Verificar balance
knitr::kable(as.data.frame(table(rotacion_balanceada$rotacion_num)),
             col.names = c("Clase","Frecuencia"),
             caption = "Distribución de la variable respuesta después de ROSE")
Distribución de la variable respuesta después de ROSE
Clase Frecuencia
0 746
1 724
# Ajuste del modelo logístico

modelo_logistico <- glm(
  rotacion_num ~ ingreso_mensual + antiguedad_cargo +
    satisfacion_laboral + horas_extra + estado_civil + viaje_de_negocios,
  data   = rotacion_balanceada,
  family = binomial()
)

# Extraer resultados ordenados
resumen <- tidy(modelo_logistico)

# Mostrar como tabla
kable(resumen, digits = 4, caption = "Resumen del modelo de regresión logística")
Resumen del modelo de regresión logística
term estimate std.error statistic p.value
(Intercept) 0.3613 0.1968 1.8356 0.0664
ingreso_mensual -0.0001 0.0000 -4.8133 0.0000
antiguedad_cargo -0.0857 0.0183 -4.6891 0.0000
satisfacion_laboral -0.2917 0.0510 -5.7174 0.0000
horas_extraSi 1.6307 0.1276 12.7846 0.0000
estado_civilDivorciado -0.2686 0.1661 -1.6168 0.1059
estado_civilSoltero 0.9287 0.1364 6.8066 0.0000
viaje_de_negociosFrecuentemente 0.7517 0.1464 5.1360 0.0000
viaje_de_negociosNo_Viaja -0.7452 0.2428 -3.0688 0.0021

La variable respuesta rotacion_num quedó balanceada:“No”: 746 y “Sí”: 724

ingreso_mensual (Estimate = -0.0001 , p < 0.001 Significativo): coeficiente negativo → a mayor ingreso, menor probabilidad de rotación.

antiguedad_cargo (Estimate = -0.0857 , p < 0.001 Significativo): coeficiente negativo.A mayor antigüedad, menor probabilidad de rotación (Cambió respecto a la hipótesis que habíamos planteado inicialmente).

satisfaccion_laboral (Estimate = -0.2917 , p < 0.001 Significativo): coeficiente negativo. A mayor satisfacción, menos rotación.

horas_extra (Estimate = 1.6307, p < 0.001 Altamente significativo): positivo. Trabajar horas extra aumenta la probabilidad de rotación.

estado_civil (Soltero:Estimate = 0.9287, p < 0.001 → Muy significativo, Divorciado Estimate = -0.2686, p = 0.106 → No significativo): Los solteros tienen más probabilidad de rotación que casados.

viaje_de_negocios (Frecuentemente (Estimate = 0.751, p < 0.001)y No viaja (Estimate = -0.745, p = 0.002) fueron significativos): Ambos influyen en la probabilidad de rotación frente a la categoría de referencia.

Interpretación:

verificación de multicolinealidad (VIF):

Antes de evaluar el poder predictivo del modelo, es necesario verificar si las variables predictoras presentan problemas de multicolinealidad, ya que esto podría afectar la estabilidad y la interpretación de los coeficientes.

# Verificar multicolinealidad
vif(modelo_logistico)
##                         GVIF Df GVIF^(1/(2*Df))
## ingreso_mensual     1.114548  1        1.055722
## antiguedad_cargo    1.093444  1        1.045679
## satisfacion_laboral 1.032446  1        1.016094
## horas_extra         1.041251  1        1.020417
## estado_civil        1.031807  2        1.007859
## viaje_de_negocios   1.020456  2        1.005075

Se verificó la presencia de multicolinealidad mediante el Factor de Inflación de la Varianza (VIF). Los valores obtenidos fueron cercanos a 1 para todas las variables predictoras, lo que indica que no existe colinealidad problemática. Por lo tanto, las variables seleccionadas pueden ser incluidas simultáneamente en el modelo de regresión logística sin riesgo de redundancia entre ellas.

7 7. Evaluación del poder predictivo del modelo

El propósito principal de los modelos es lograr predecir adecuadamente la rotación de empleados. Para evaluar este desempeño, utilizamos la Curva ROC y el AUC:

Curva ROC: permite distinguir entre empleados que rotan y los que no. En un modelo perfecto, la curva se aproximaría a la esquina superior izquierda del gráfico, indicando alta sensibilidad y especificidad.

AUC (Área bajo la curva ROC): mide el poder discriminatorio del modelo. Un valor cercano a 0.5 indica que el modelo no tiene capacidad predictiva (equivalente al azar). Un valor cercano a 1.0 indica un modelo perfecto. De forma práctica, un AUC > 0.7 se considera aceptable, y un AUC > 0.8 se considera bueno.

# Predecir probabilidades con el modelo logístico
probabilidades <- predict(modelo_logistico, type = "response")

# Crear el objeto ROC (usamos la verdad y las probabilidades)
roc_obj <- roc(rotacion_balanceada$rotacion_num, probabilidades)

#Calcular el AUC
auc_valor <- auc(roc_obj)
print(paste("El valor del AUC es:", round(auc_valor, 3)))
## [1] "El valor del AUC es: 0.798"
# Graficar la curva ROC
plot(roc_obj,
     main = "Curva ROC del Modelo Logístico",
     col = "blue", lwd = 2)

# Línea de referencia (modelo al azar)
abline(a = 0, b = 1, lty = 2, col = "gray")

# Agregar leyenda con el valor de AUC
legend("bottomright",
       legend = paste("AUC =", round(auc_valor, 2)),
       col = "blue", lwd = 2)

Interpretación: La curva azul se aleja claramente de la diagonal (línea gris), lo que indica que el modelo sí logra diferenciar entre empleados que rotan y los que no. El modelo logístico obtuvo un AUC = 0.80, lo que indica una capacidad predictiva muy buena.

8 8. Predicciones

Para hacer este ejercicio vamos a tomar 2 casos extremos del análisis descriptivo EDA.

*Un perfil de empleado con bajo riesgo de rotación (ej. alto salario, alta satisfacción, casado, sin horas extra, rara vez viaja).

*Un perfil de empleado con alto riesgo de rotación (ej. bajo salario, baja satisfacción, soltero, trabaja horas extra, viaja frecuentemente).

8.1 8.1 Perfil Bajo riesgo de rotación

ingreso_mensual = 6000,
antiguedad_cargo = 10,
satisfacion_laboral = 4,
horas_extra = “No”, estado_civil = “Casado”, viaje_de_negocios = “Raramente”

# Caso 1: Bajo riesgo de rotación
empleado_estable <- data.frame(
  ingreso_mensual = 6000,        # salario alto
  antiguedad_cargo = 10,         # muchos años en el cargo
  satisfacion_laboral = 4,      # muy satisfecho
  horas_extra = "No",
  estado_civil = "Casado",
  viaje_de_negocios = "Raramente"
)

8.2 8.2 Perfil Alto riesgo de rotación

ingreso_mensual = 1200,
antiguedad_cargo = 1,
satisfacion_laboral = 1,
horas_extra = “Si”, estado_civil = “Soltero”, viaje_de_negocios = “Frecuentemente”

# Caso 2: Alto riesgo de rotación
empleado_inestable <- data.frame(
  ingreso_mensual = 1200,        # salario bajo
  antiguedad_cargo = 1,          # poco tiempo en el cargo
  satisfacion_laboral = 1,      # insatisfecho
  horas_extra = "Si",
  estado_civil = "Soltero",
  viaje_de_negocios = "Frecuentemente"
)

Para esto estimamos un punto de corte:

# Probabilidades predichas del modelo
probabilidades <- predict(modelo_logistico, type = "response")

# Crear objeto ROC
roc_obj <- roc(rotacion_balanceada$rotacion_num, probabilidades)

# Calcular el mejor punto de corte según índice de Youden
corte_optimo <- coords(roc_obj, "best", ret = "threshold", best.method = "youden")

print(paste("El mejor punto de corte es:", round(corte_optimo, 3)))
## [1] "El mejor punto de corte es: 0.549"

El modelo encontró que el umbral más adecuado es 0.549, lo cual mejora la capacidad predictiva.

A continuación se realizan las predicciones del modelo:

# Predicciones
prob_estable <- predict(modelo_logistico, newdata = empleado_estable, type = "response")
# Clasificación con corte 0.549
corte <- 0.549
pred_estable <- ifelse(prob_estable >= corte, "Si rota", "No rota")
##                  Empleado Prob_Rotacion Prediccion
## 1   Estable (bajo riesgo)         0.110    No rota
## 2 Inestable (alto riesgo)         0.961    Si rota

Interpretación:

El empleado estable (bajo riesgo), con alto salario, antigüedad en el cargo, alta satisfacción laboral, sin horas extra, casado y con viajes de negocios poco frecuentes, tiene una probabilidad de rotación del 11%, lo que se interpreta como un bajo riesgo de abandonar la organización. El modelo lo clasifica como “No rota”.

El empleado inestable (alto riesgo), con bajo salario, poca antigüedad, baja satisfacción laboral, soltero, que trabaja horas extra y viaja frecuentemente, presenta una probabilidad de rotación del 96%, siendo clasificado como “Sí rota”. Este caso representa un perfil que requiere atención prioritaria en la gestión de talento, ya que su permanencia en la empresa está altamente comprometida.

9 9. Conclusiones y estrategias

Conclusiones

Ingreso mensual: los empleados con salarios más bajos tienen una mayor probabilidad de rotar. Esto confirma que los factores económicos son determinantes.

Antigüedad en el cargo: contrario a la hipótesis inicial, los empleados con mayor antigüedad tienden a permanecer más. Esto sugiere que la rotación ocurre más en etapas tempranas del empleo.

Satisfacción laboral: A mayor satisfacción, menor rotación. Esto muestra la importancia del clima y ambiente organizacional.

Horas extra: trabajar horas adicionales aumenta de manera muy significativa la probabilidad de rotación.

Estado civil: los solteros presentan mayor riesgo de rotación frente a los casados.

Viajes de negocios: viajar frecuentemente o no viajar en absoluto se asocia con mayor probabilidad de rotación, frente a quienes viajan rara vez.

Estrategias para disminuir la rotación

*Mejorar los incentivos económicos:Ajustar escalas salariales o implementar bonos de retención, especialmente en los primeros años.Establecer aumentos periódicos y transparentes.

*Plan de carrera y crecimiento interno: Diseñar programas de promoción y desarrollo que motiven a los empleados a permanecer en la organización.

*Ambiente laboral y satisfacción:Implementar encuestas periódicas de satisfacción laboral.

*Gestión de carga laboral: Redistribuir horas extra.contratar más personal o reorganizar turnos.

*Fomentar el equilibrio trabajo-vida personal: Flexibilidad y balance en viajes de negocios. Reducir la frecuencia de viajes o compensarlos con beneficios (días libres, bonos).

*Diseñar programas específicos de retención para empleados solteros (mayor riesgo de rotación).

*Promover actividades sociales y de integración para fortalecer su sentido de pertenencia.