library(dplyr)
library(readr)
library(ggplot2)
library(scales)
library(knitr)
library(plotly)
library(kableExtra)
library(reactable)
library(broom)
library(reshape2)

1. Introducción

El ingreso laboral constituye uno de los principales elementos para analizar las condiciones económicas de la población y las diferencias existentes dentro del mercado de trabajo colombiano. Los ingresos que reciben las personas por su actividad laboral están relacionados con diferentes características individuales y laborales, entre ellas el nivel educativo alcanzado, la edad, el sexo, la cantidad de horas trabajadas y la permanencia en el empleo. Analizar estas relaciones permite comprender de mejor manera por qué los ingresos pueden presentar diferencias importantes entre los trabajadores.

En Colombia, estas diferencias adquieren especial relevancia debido a las desigualdades que pueden presentarse en el acceso al empleo y en las condiciones bajo las cuales las personas participan en el mercado laboral. Por ejemplo, para el trimestre móvil diciembre de 2023 - febrero de 2024, el DANE reportó una tasa de ocupación de 69,3 % para los hombres y de 44,4 % para las mujeres, evidenciando una diferencia de 24,9 puntos porcentuales en la participación efectiva en el mercado laboral. De igual manera, la tasa de desocupación fue de 9,4 % para los hombres y de 14,2 % para las mujeres. Estas diferencias muestran la importancia de considerar el sexo como una característica relevante al estudiar las condiciones laborales de la población. DANE,boletín técnico 2024

El nivel educativo también representa una característica importante dentro del mercado laboral. Según el DANE, durante 2024 la educación media concentró el 36,7 % de la fuerza de trabajo nacional, seguida por la educación básica primaria con 17,9 %, la educación técnica profesional y tecnológica con 12,6 % y la educación universitaria con 12,1 %. Esta composición evidencia la diversidad de niveles de formación presentes entre las personas que participan en el mercado laboral y plantea la necesidad de analizar si las diferencias en educación están relacionadas con los ingresos obtenidos por los trabajadores. DANE,boletín F.L 2024

A estas características se suman las condiciones propias del empleo. La edad puede relacionarse con la experiencia laboral y, por tanto, con la capacidad de obtener mayores ingresos, aunque esta relación no necesariamente se mantiene de manera constante durante todo el ciclo laboral. Asimismo, la cantidad de horas trabajadas semanalmente representa una medida de la intensidad del trabajo, mientras que los meses de permanencia en el empleo permiten aproximarse a la antigüedad o estabilidad laboral. Por esta razón, considerar conjuntamente estas características permite realizar un análisis más amplio de los factores asociados con las diferencias observadas en los ingresos laborales.

Para estudiar esta problemática se utilizan los microdatos de la Gran Encuesta Integrada de Hogares (GEIH) del DANE, específicamente la información correspondiente a febrero de 2024. Esta operación estadística proporciona información sobre el mercado laboral y los ingresos de la población, además de características sociodemográficas como sexo, edad y nivel educativo. En particular, la base de personas ocupadas contiene la variable INGLABO, correspondiente a los ingresos laborales. Fuente: DANE, Microdatos de la Gran Encuesta Integrada de Hogares (GEIH) 2024

En este contexto, el presente estudio busca analizar de qué manera las características sociodemográficas y las condiciones laborales de las personas ocupadas se relacionan con su nivel de ingreso laboral en Colombia. Para ello, se emplea un modelo de regresión lineal múltiple utilizando como variable dependiente el logaritmo natural del ingreso laboral y como variables explicativas el sexo, el nivel educativo, la edad, la edad al cuadrado, las horas trabajadas semanalmente y los meses en el empleo. De esta manera, se pretende identificar y cuantificar la asociación entre estas características y el ingreso laboral, teniendo en cuenta simultáneamente los diferentes factores incluidos en el modelo.

2. Metodología

2.1 Método empleado

El presente estudio utiliza un enfoque cuantitativo y de carácter correlacional, debido a que busca analizar estadísticamente la relación existente entre determinadas características de las personas ocupadas y su ingreso laboral. Para desarrollar este análisis se emplea un modelo de regresión lineal múltiple, el cual permite estudiar de manera conjunta la relación entre una variable dependiente y varias variables explicativas.

El estudio parte de la siguiente pregunta de investigación: ¿De qué manera influyen las características sociodemográficas (sexo y nivel educativo) y las condiciones laborales (edad, horas trabajadas a la semana y meses en el empleo) en la determinación del ingreso laboral de los trabajadores en Colombia? A partir de esta pregunta se establece el procedimiento de análisis y se seleccionan los elementos necesarios para construir el modelo econométrico.

La información utilizada proviene de la Gran Encuesta Integrada de Hogares (GEIH) del DANE, una operación estadística que proporciona información sobre el mercado laboral, los ingresos laborales y las características sociodemográficas de la población residente en Colombia. Esta fuente resulta adecuada para el estudio, ya que permite relacionar información sobre los ingresos de las personas con diferentes características individuales y laborales. Fuente: DANE, Gran Encuesta Integrada de Hogares (GEIH) 2024

El procedimiento metodológico se desarrolla de manera progresiva. En una primera etapa se realiza la exploración de los datos seleccionados, con el propósito de conocer su comportamiento general y detectar posibles situaciones que puedan afectar el análisis, como valores atípicos o comportamientos inusuales en las variables. Esta revisión inicial permite tener una mejor comprensión de la información antes de realizar la estimación del modelo.

Posteriormente, se establece la especificación del modelo de regresión lineal múltiple de acuerdo con la pregunta de investigación. La selección de las variables se realiza considerando su relación con el problema estudiado y la información disponible en la base de datos, buscando que cada una tenga una justificación dentro del análisis. De esta manera, el modelo se construye teniendo en cuenta tanto los aspectos estadísticos como la relación de las variables con las características del mercado laboral.

Una vez definida la especificación, se procede a estimar el modelo utilizando el programa estadístico R. A partir de la estimación se analizarán los coeficientes obtenidos, su significancia estadística y la capacidad explicativa del modelo mediante indicadores como el coeficiente de determinación (R²) y el coeficiente de determinación ajustado. También se considerará la significancia global del modelo para determinar si, en conjunto, las variables incluidas aportan información relevante para explicar las variaciones observadas en el ingreso laboral.

Como parte del procedimiento también se realizará la evaluación de los supuestos del modelo. Para ello se utilizarán diferentes herramientas gráficas y estadísticas que permitan analizar el comportamiento de los residuos, la linealidad, la normalidad y la homocedasticidad. Asimismo, se evaluará la posible presencia de multicolinealidad entre las variables explicativas mediante el factor de inflación de la varianza (VIF) y se revisarán posibles observaciones con una influencia considerable sobre los resultados mediante la distancia de Cook. Estos análisis permitirán determinar si el modelo presenta condiciones adecuadas para realizar su interpretación.

Finalmente, los resultados serán analizados teniendo en cuenta la pregunta de investigación y el contexto del mercado laboral colombiano. La interpretación se enfocará en las asociaciones encontradas entre las variables incluidas y el ingreso laboral, sin asumir que dichas relaciones representan necesariamente efectos causales, debido a que el estudio se basa en información observacional. De esta manera, el método empleado permite desarrollar el análisis desde la exploración inicial de los datos hasta la estimación y evaluación del modelo de regresión lineal múltiple.

2.2 Variables

Para la construcción del modelo de regresión lineal múltiple se definió una variable dependiente relacionada con el ingreso laboral y un conjunto de variables independientes asociadas con características sociodemográficas y condiciones laborales. La selección de estas variables se realizó teniendo en cuenta la pregunta de investigación y su pertinencia para analizar las diferencias observadas en los ingresos de las personas ocupadas.

Variable dependiente

Ingreso laboral (ln_ingreso)

La variable dependiente corresponde al ingreso laboral, representado en el modelo mediante el logaritmo natural de la variable Ingreso, denominada ln_ingreso. El ingreso laboral corresponde a los ingresos obtenidos por la persona como resultado de su actividad laboral. La transformación mediante logaritmo natural permite trabajar los ingresos en una escala más adecuada para el análisis, teniendo en cuenta las diferencias que pueden presentarse entre los valores de ingreso de los trabajadores. La variable Ingreso se encuentra disponible en la base de personas ocupadas de la GEIH.

Variables independientes

Sexo (sexo)

La variable sexo es de naturaleza cualitativa y permite clasificar a las personas en las categorías Hombre y Mujer. Se incorpora al modelo debido a que constituye una característica sociodemográfica relevante para estudiar posibles diferencias en el ingreso laboral entre los trabajadores. Al ser una variable categórica, su incorporación al modelo se realiza mediante categorías que permiten establecer comparaciones entre los grupos.

Nivel educativo (nivel_educ_grupo)

El nivel educativo es una variable cualitativa ordinal que representa el máximo nivel de formación alcanzado por la persona. Para el análisis se consideran cinco categorías: Primaria, Secundaria, Técnico o tecnólogo, Pregrado y Posgrado. Esta variable se incluye debido a que el nivel de formación constituye una característica importante para analizar las diferencias en los ingresos laborales, ya que permite comparar el comportamiento del ingreso entre personas con diferentes niveles educativos.

Edad (edad)

La edad es una variable cuantitativa continua expresada en años. Se incorpora al modelo porque puede estar relacionada con la experiencia y la trayectoria laboral de las personas. Su inclusión permite analizar la asociación entre la edad y el ingreso laboral, considerando simultáneamente las demás variables incluidas en el modelo.

Edad al cuadrado (edad_sq)

La edad al cuadrado corresponde a una transformación de la variable edad y se incorpora para considerar una posible relación no lineal entre la edad y el ingreso laboral. Esto permite que el efecto asociado con la edad pueda variar a medida que aumentan los años, en lugar de asumir que la relación permanece constante durante todo el ciclo laboral.

Horas trabajadas por semana (horas_semana)

Las horas trabajadas por semana son una variable cuantitativa continua que representa la cantidad de horas dedicadas a la actividad laboral durante una semana. Esta variable se incorpora como una medida de la intensidad laboral y permite analizar su asociación con el ingreso obtenido por los trabajadores.

Meses en el empleo (meses_trabajo)

Los meses en el empleo son una variable cuantitativa continua que representa el tiempo de permanencia de la persona en su empleo actual, expresado en meses. Se incluye como una aproximación a la antigüedad laboral, con el propósito de analizar si el tiempo de permanencia en el empleo presenta alguna relación con el ingreso laboral.

En conjunto, las variables seleccionadas permiten incorporar al análisis tanto características personales y sociodemográficas como aspectos relacionados con las condiciones laborales. De esta manera, el modelo busca analizar el ingreso laboral considerando simultáneamente diferentes factores relevantes para la situación laboral de las personas ocupadas en Colombia. La estructura de variables utilizada corresponde a la planteada en el estudio a partir de los microdatos de la GEIH.

2.3 Descripción del modelo

El modelo de regresión lineal múltiple se plantea con el propósito de analizar la asociación entre el ingreso laboral y las características sociodemográficas y laborales seleccionadas para el estudio. La variable dependiente corresponde al logaritmo natural del ingreso laboral y el modelo incorpora las variables explicativas descritas en la siguiente tabla.

library(knitr)
library(kableExtra)

variables_modelo <- data.frame(
  Variable = c(
    "ln(Ingreso)",
    "β₀",
    "Sexo",
    "Nivel educativo",
    "Edad",
    "Edad²",
    "Horas/semana",
    "Meses en el empleo",
    "ε"
  ),
  Descripción = c(
    "Logaritmo natural del ingreso laboral",
    "Término constante (intercepto) del modelo",
    "Sexo de la persona ocupada",
    "Máximo nivel educativo alcanzado",
    "Edad de la persona",
    "Edad elevada al cuadrado",
    "Horas trabajadas durante una semana",
    "Tiempo de permanencia en el empleo actual",
    "Término de error aleatorio"
  ),
  Tipo_Variable = c(
    "Variable dependiente (transformada)",
    "Parámetro",
    "Categórica",
    "Categórica ordinal",
    "Cuantitativa",
    "Cuantitativa",
    "Cuantitativa",
    "Cuantitativa",
    "Error"
  ),
  Ejemplos_Notas = c(
    "Transformación logarítmica del ingreso laboral en COP",
    "Valor base del modelo",
    "Hombre y Mujer",
    "Primaria o menos, Secundaria, Técnico o tecnólogo, Pregrado y Posgrado",
    "Años cumplidos",
    "Permite considerar una posible relación no lineal con el ingreso",
    "Horas/semana",
    "Meses",
    "Representa factores no observados en el modelo"
  )
)

tabla <- kable(
  variables_modelo,
  format = "html",
  col.names = c(
    "Variable",
    "Descripción",
    "Tipo de Variable",
    "Notas"
  ),
  align = c("l", "l", "l", "l"),
  caption = "Tabla 1. Variables del Modelo de Regresión"
) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed"),
    full_width = FALSE,
    font_size = 14,
    position = "center"
  ) %>%
  row_spec(
    0,
    background = "#7A1F2B",
    color = "white",
    bold = TRUE
  ) %>%
  column_spec(1, bold = TRUE, width = "3cm") %>%
  column_spec(2, width = "4.5cm") %>%
  column_spec(3, width = "3.5cm") %>%
  column_spec(4, width = "5cm") %>%
  footnote(
    general = "Elaboración propia con base en los microdatos de la GEIH 2024 del DANE.",
    general_title = "Nota:",
    footnote_as_chunk = TRUE
  )

tabla
Tabla 1. Variables del Modelo de Regresión
Variable Descripción Tipo de Variable Notas
ln(Ingreso) Logaritmo natural del ingreso laboral Variable dependiente (transformada) Transformación logarítmica del ingreso laboral en COP
β₀ Término constante (intercepto) del modelo Parámetro Valor base del modelo
Sexo Sexo de la persona ocupada Categórica Hombre y Mujer
Nivel educativo Máximo nivel educativo alcanzado Categórica ordinal Primaria o menos, Secundaria, Técnico o tecnólogo, Pregrado y Posgrado
Edad Edad de la persona Cuantitativa Años cumplidos
Edad² Edad elevada al cuadrado Cuantitativa Permite considerar una posible relación no lineal con el ingreso
Horas/semana Horas trabajadas durante una semana Cuantitativa Horas/semana
Meses en el empleo Tiempo de permanencia en el empleo actual Cuantitativa Meses
ε Término de error aleatorio Error Representa factores no observados en el modelo
Nota: Elaboración propia con base en los microdatos de la GEIH 2024 del DANE.

Las variables presentadas en la tabla conforman la estructura utilizada para especificar el modelo de regresión lineal múltiple. Las variables categóricas, como sexo y nivel educativo, se incorporan mediante categorías de referencia para permitir la comparación entre grupos.

La variable dependiente se expresa como el logaritmo natural del ingreso laboral (ln(Ingreso)). Esta transformación se utiliza debido a las diferencias existentes entre los niveles de ingreso observados en la base, permitiendo reducir la escala de los valores y representar de una manera más adecuada la distribución del ingreso para el análisis de regresión. La variable INGLABO corresponde a los ingresos laborales registrados para las personas ocupadas en la GEIH 2024. DANE, GEIH 2024

2.3.1 Ecuación del modelo

La ecuación del modelo de regresión lineal múltiple se construye a partir de la pregunta de investigación y de las variables seleccionadas para analizar la relación entre las características de las personas ocupadas y su ingreso laboral. El objetivo es estimar la asociación entre el ingreso laboral y las variables sociodemográficas y laborales incluidas, considerando simultáneamente los diferentes factores del modelo.

Ecuación del modelo

\[ \begin{aligned} \ln(\text{Ingreso}_i) = \beta_0 &+ \beta_1 \text{Sexo Mujer}_i + \beta_2 \text{Educ Secundaria}_i + \beta_3 \text{Educ Técnica}_i \\ &+ \beta_4 \text{Educ Universitaria}_i + \beta_5 \text{Educ Posgrado}_i + \beta_6 \text{Edad}_i \\ &+ \beta_7 \text{Edad}_i^2 + \beta_8 \text{Horas Semana}_i + \beta_9 \text{Meses Trabajo}_i + \varepsilon_i \end{aligned} \] Donde \(\ln(Ingreso)\) representa el logaritmo natural del ingreso laboral y corresponde a la variable dependiente del modelo. El término \(\beta_0\) representa el intercepto, mientras que cada coeficiente \(\beta_j\) representa la asociación de la respectiva variable explicativa con el logaritmo del ingreso laboral, manteniendo constantes las demás variables incluidas en el modelo.

La variable Sexo representa la característica sociodemográfica asociada al sexo de la persona ocupada, mientras que NivelEducativo corresponde al máximo nivel educativo alcanzado. Debido a su naturaleza categórica, ambas variables se incorporan al modelo mediante variables indicadoras, utilizando categorías de referencia para realizar las comparaciones entre grupos.

La variable Edad representa la edad de la persona en años y Edad² corresponde a su término cuadrático. La inclusión de este último permite considerar una posible relación no lineal entre la edad y el ingreso laboral. Por su parte, HorasSemana representa la cantidad de horas trabajadas durante una semana y MesesTrabajo corresponde al tiempo de permanencia en el empleo actual.

Finalmente, \(\varepsilon\) representa el término de error aleatorio y recoge aquellos factores que pueden estar relacionados con el ingreso laboral pero que no se encuentran incluidos explícitamente en el modelo. De esta manera, la ecuación reúne las variables seleccionadas para estimar la relación conjunta entre las características sociodemográficas y laborales y el ingreso laboral de las personas ocupadas.

2.4 Base de datos

Para el presente trabajo se utilizan los datos de la Gran Encuesta Integrada de Hogares (GEIH) 2024, descargados directamente de la página oficial del DANE. A partir de estos datos se seleccionaron y organizaron las variables de interés para el análisis del ingreso laboral y la construcción del modelo de regresión lineal múltiple.

library(tidyverse)
library(reactable)
library(htmltools)
library(dplyr)

caracteristicas <- read.csv(
  "Características generales, seguridad social en salud y educación.CSV",
  sep = ";",
  fileEncoding = "latin1"
)

ocupados <- read.csv(
  "Ocupados.CSV",
  sep = ";",
  fileEncoding = "latin1"
)

Base_datos <- caracteristicas %>%
  select(PERIODO, DIRECTORIO, SECUENCIA_P, ORDEN, P3271, P6040, P3042) %>%
  inner_join(
    ocupados %>%
      select(PERIODO, DIRECTORIO, SECUENCIA_P, ORDEN, P6800, P6426, INGLABO),
    by = c("PERIODO", "DIRECTORIO", "SECUENCIA_P", "ORDEN")
  ) %>%
  filter(
    INGLABO > 0,
    !is.na(P3271),
    !is.na(P6040),
    !is.na(P3042),
    !is.na(P6800),
    !is.na(P6426)
  ) %>%
  mutate(
    sexo = case_when(
      P3271 == 1 ~ "Hombre",
      P3271 == 2 ~ "Mujer",
      TRUE ~ "No especificado"
    ),
    nivel_educ_grupo = case_when(
      P3042 %in% c(1, 2, 3) ~ "Primaria",
      P3042 %in% c(4, 5, 6, 7) ~ "Secundaria",
      P3042 %in% c(8, 9) ~ "Técnico o tecnólogo",
      P3042 == 10 ~ "Pregrado",
      P3042 %in% c(11, 12, 13) ~ "Posgrado",
      TRUE ~ "No especificado"
    ),
    edad = P6040,
    edad_sq = edad^2,
    horas_semana = P6800,
    meses_trabajo = P6426,
    ln_ingreso = log(INGLABO)
  ) %>%
  select(
    sexo,
    nivel_educ_grupo,
    edad,
    edad_sq,
    horas_semana,
    meses_trabajo,
    INGLABO,
    ln_ingreso
  )

div(
  style = "font-family: Georgia, serif; margin-bottom: 25px;",
  
  div(
    style = "text-align: center; margin-bottom: 12px;",
    tags$span(style = "color: #7A1F2B; font-weight: bold; font-size: 16px;", "Tabla 2."),
    tags$span(style = "color: #2B2D42; font-size: 15px; font-weight: bold;", " Muestra consolidada de microdatos de ocupados y sus variables de estudio")
  ),
  
  reactable(
    Base_datos,
    defaultPageSize = 15,
    showPageSizeOptions = TRUE,
    pageSizeOptions = c(10, 15, 25, 50),
    striped = TRUE,
    highlight = TRUE,
    bordered = TRUE,
    filterable = TRUE,
    resizable = TRUE,
    wrap = FALSE,
    defaultColDef = colDef(
      align = "center",
      minWidth = 120
    ),
    theme = reactableTheme(
      color = "#2B2D42",
      backgroundColor = "#FFFFFF",
      borderColor = "#E8E4E1",
      stripedColor = "#FDF0F0",
      highlightColor = "#F7E9EB",
      cellPadding = "10px 12px",
      style = list(
        fontFamily = "Georgia, serif",
        fontSize = "13.5px"
      ),
      headerStyle = list(
        backgroundColor = "#7A1F2B",
        color = "#FFFFFF",
        fontWeight = "bold",
        fontSize = "14px",
        borderBottom = "3px solid #C7A64A"
      ),
      paginationStyle = list(
        color = "#7A1F2B",
        fontWeight = "bold"
      ),
      pageButtonHoverStyle = list(
        backgroundColor = "#7A1F2B",
        color = "#FFFFFF"
      ),
      pageButtonActiveStyle = list(
        backgroundColor = "#D90429",
        color = "#FFFFFF"
      ),
      searchInputStyle = list(
        borderColor = "#C7A64A",
        padding = "6px 12px",
        borderRadius = "6px"
      )
    ),
    columns = list(
      sexo = colDef(name = "Sexo"),
      nivel_educ_grupo = colDef(name = "Nivel educativo"),
      edad = colDef(name = "Edad"),
      edad_sq = colDef(name = "Edad al cuadrado"),
      horas_semana = colDef(name = "Horas a la semana"),
      meses_trabajo = colDef(name = "Meses en el empleo"),
      INGLABO = colDef(
        name = "Ingreso laboral (COP)",
        format = colFormat(separators = TRUE, currency = "COP", digits = 0)
      ),
      ln_ingreso = colDef(
        name = "Logaritmo del ingreso",
        format = colFormat(digits = 4)
      )
    )
  ),
  
  div(
    style = "font-size: 11.5px; color: #6C757D; margin-top: 8px; font-style: italic;",
    tags$b("Fuente: "), "Elaboración propia con base en microdatos de la Gran Encuesta Integrada de Hogares (GEIH) del DANE."
  )
)
Tabla 2. Muestra consolidada de microdatos de ocupados y sus variables de estudio
Fuente: Elaboración propia con base en microdatos de la Gran Encuesta Integrada de Hogares (GEIH) del DANE.

3. Analisis Univariado de las Variables del Modelo

3.1 Variable Dependiente

3.1.1 Logaritmo del Ingreso Laboral en Colombia

La Tabla 1 presenta las estadísticas descriptivas del logaritmo natural del ingreso laboral mensual de las 28.272 personas ocupadas de la muestra (GEIH, DANE, febrero de 2024), que es la variable que el modelo busca predecir.

asimetria <- function(x) mean((x - mean(x))^3) / sd(x)^3

tabla_ln <- df_modelo %>%
  summarise( N = n(), Media = round(mean(ln_ingreso), 3),Mediana= round(median(ln_ingreso), 3),Desv      = round(sd(ln_ingreso), 3), Minimo    = round(min(ln_ingreso), 3),Maximo    = round(max(ln_ingreso), 3),Asimetria = round(asimetria(ln_ingreso), 3))

tabla_ln %>%
  kbl(
    caption = "Tabla 3. Estadísticas descriptivas del logaritmo natural del ingreso laboral mensual",
    align = rep("r", 7),
    col.names = c("N", "Media", "Mediana", "Desv. Estándar", "Mínimo", "Máximo", "Asimetría"),
    format.args = list(big.mark = ".", decimal.mark = ",")
  ) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed"),
    full_width = FALSE, font_size = 14, position = "center"
  ) %>%
  row_spec(0, background = "#7A1F2B", color = "white", bold = TRUE) %>%
  column_spec(2:3, bold = TRUE, color = "#7A1F2B") %>%
  footnote(
    general = "Elaboración propia con base en microdatos GEIH DANE",
    general_title = "Fuente:",
    footnote_as_chunk = TRUE
  )
Tabla 3. Estadísticas descriptivas del logaritmo natural del ingreso laboral mensual
N Media Mediana Desv. Estándar Mínimo Máximo Asimetría
28.272 13,874 14,078 0,932 3,912 18,421 -0,693
Fuente: Elaboración propia con base en microdatos GEIH DANE

El logaritmo natural del ingreso laboral mensual tiene una media de 13,874, una mediana de 14,078 y una desviación estándar de 0,932. Es decir que la mediana equivale a un ingreso cerca de $1.300.000 lo cual es inferior al promedio de $1.594.834 (Tabla 2), por lo que se asume que hay ingresos muy altos que hacen que el promedio se eleve. En pesos, la desviación estándar corresponde a $2.341.943,es mayor que el promedio, y esa dispersión hace que unos casos dominen el modelo. Por eso en el modelo usamos el ln(ingreso) para reducir esa dispersión.

media <- mean(df_modelo$ln_ingreso)
mediana <- median(df_modelo$ln_ingreso)
asim <- asimetria(df_modelo$ln_ingreso)

ggplot(df_modelo, aes(x = ln_ingreso)) +
  geom_histogram(bins = 40, fill = "#7A1F2B", color = "#FCFAF8", alpha = 0.9) +
  geom_vline(aes(xintercept = media, color = "Media"), linetype = "dashed", linewidth = 1) +
  geom_vline(aes(xintercept = mediana, color = "Mediana"), linetype = "dotted", linewidth = 1) +
  scale_color_manual(
    name = "Medidas:",
    values = c("Media" = "#C7A64A", "Mediana" = "#D90429")
  ) +
  labs(
    title = "Figura 1. Distribución del logaritmo natural del ingreso laboral mensual",
    subtitle = paste0("Asimetría = ", round(asim, 3), " | Media = ", round(media, 2), " | Mediana = ", round(mediana, 2)),
    x = "Ln(ingreso laboral mensual)",
    y = "Frecuencia",
    caption = "Fuente: Elaboración propia con base en microdatos GEIH DANE"
  ) +
  theme_minimal(base_size = 13, base_family = "Georgia") +
  theme(
    plot.title = element_text(face = "bold", size = 13, color = "#7A1F2B", margin = margin(b = 5)),
    plot.subtitle = element_text(size = 11, color = "#2B2D42", margin = margin(b = 15)),
    plot.caption = element_text(hjust = 0, size = 9, color = "#6C757D", face = "italic", margin = margin(t = 12)),
    axis.title = element_text(face = "bold", color = "#2B2D42", size = 11),
    axis.text = element_text(color = "#2B2D42"),
    panel.grid.major = element_line(color = "#E8E4E1", linewidth = 0.4),
    panel.grid.minor = element_blank(),
    legend.position = "top",
    legend.justification = "right",
    legend.title = element_text(face = "bold", size = 10, color = "#7A1F2B"),
    legend.text = element_text(size = 10, color = "#2B2D42")
  )

3.1.2 Ingreso laboral según las características de las personas

Los resultados del análsis descriptivo del ingreso laboral mensual de las personas de la muestra en Colombia, presentados en la Tabla 2, revelan caracteristicas que ayudan a comprender que factores son los determinantes del ingreso.

df_b <- df_modelo %>%
  mutate(
    edad_grupo = cut(edad, breaks = c(-Inf, 24, 34, 44, 54, 64, Inf),
                     labels = c("Hasta 24 años", "25 a 34 años", "35 a 44 años", "45 a 54 años", "55 a 64 años", "65 años o más")),horas_grupo = cut(horas_semana, breaks = c(-Inf, 30, 48, Inf),labels = c("Hasta 30 horas", "31 a 48 horas", "Más de 48 horas")),meses_grupo = cut(meses_trabajo, breaks = c(-Inf, 12, 60, Inf),labels = c("Hasta 12 meses", "13 a 60 meses", "Más de 60 meses")))

resumen_dep <- function(df, var) {
  df %>%
    group_by(Categoria = {{ var }}) %>%
    summarise(
      `N Observaciones`        = n(),
      `Ingreso Promedio`       = round(mean(ingreso, na.rm = TRUE), 2),
      `Desv. Estándar Ingreso` = round(sd(ingreso, na.rm = TRUE), 2),
      `Ingreso Mínimo`         = min(ingreso, na.rm = TRUE),
      `Ingreso Máximo`         = max(ingreso, na.rm = TRUE),
      `Media Ln`
= round(mean(ln_ingreso,na.rm = TRUE),3),
      .groups = "drop"
   ) %>%
    mutate(Categoria = as.character(Categoria))
}

total <- df_b %>%
  summarise(
    Categoria                = "Total muestra",
    `N Observaciones`        = n(),
    `Ingreso Promedio`       = round(mean(ingreso, na.rm = TRUE), 2),
    `Desv. Estándar Ingreso` = round(sd(ingreso, na.rm = TRUE), 2),
    `Ingreso Mínimo`         = min(ingreso, na.rm = TRUE),
    `Ingreso Máximo`         = max(ingreso, na.rm = TRUE),
    `Media Ln`               =
round(mean(ln_ingreso,na.rm = TRUE),3)
)

tabla_caract <- bind_rows(resumen_dep(df_b, sexo),resumen_dep(df_b, nivel_educ_grupo),resumen_dep(df_b, edad_grupo),resumen_dep(df_b, horas_grupo), resumen_dep(df_b, meses_grupo),  total)

tabla_caract %>%
  kbl(
    caption = "Tabla 4. Estadísticas descriptivas del ingreso laboral (en pesos y logaritmo natural) según las variables categoricas",
    align = c("l", "r", "r", "r", "r", "r","r"),
    col.names = c("Categoría", "N", "Ingreso promedio (COP)", "Desv. Estándar", "Mínimo", "Máximo","Media de Ln(ingreso)"),
    format.args = list(big.mark = ".", decimal.mark = ",")
  ) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed"),
    full_width = FALSE, font_size = 14, position = "center"
  ) %>%
  row_spec(0, background = "#7A1F2B", color = "#FFFFFF", bold = TRUE) %>%
  column_spec(1, bold = TRUE, width = "5cm") %>%
  column_spec(2:7, width = "2.5cm") %>%
  column_spec(7, bold = TRUE, background = "#FDF0F0", color = "#7A1F2B") %>%
  pack_rows("Sexo", 1, 2, label_row_css = "background-color: #F7E9EB; color: #7A1F2B; font-weight: bold;") %>%
  pack_rows("Nivel educativo", 3, 7, label_row_css = "background-color: #F7E9EB; color: #7A1F2B; font-weight: bold;") %>%
  pack_rows("Edad", 8, 13, label_row_css = "background-color: #F7E9EB; color: #7A1F2B; font-weight: bold;") %>%
  pack_rows("Horas trabajadas a la semana", 14, 16, label_row_css = "background-color: #F7E9EB; color: #7A1F2B; font-weight: bold;") %>%
  pack_rows("Meses en el trabajo", 17, 19, label_row_css = "background-color: #F7E9EB; color: #7A1F2B; font-weight: bold;") %>%
  row_spec(20, bold = TRUE, background = "#F9F3E3", color = "#7A1F2B") %>%
  footnote(
    general = "Elaboración propia con base en microdatos GEIH DANE.",
    general_title = "Fuente:",
    footnote_as_chunk = TRUE
  )
Tabla 4. Estadísticas descriptivas del ingreso laboral (en pesos y logaritmo natural) según las variables categoricas
Categoría N Ingreso promedio (COP) Desv. Estándar Mínimo Máximo Media de Ln(ingreso)
Sexo
Hombre 15.804 1.657.886,6 2.474.194,4 50 100.000.000 13,964
Mujer 12.468 1.514.911,2 2.160.171,0 60 100.000.000 13,759
Nivel educativo
Primaria o menos 5.710 835.339,6 863.653,9 50 39.560.000 13,321
Secundaria / Media 12.719 1.151.819,1 1.272.681,1 8.000 87.860.000 13,707
Técnica / Tecnológica 3.809 1.558.756,4 1.652.242,6 5.000 47.900.000 14,026
Universitaria 4.416 2.485.690,0 2.811.846,0 60 100.000.000 14,431
Posgrado 1.618 5.411.166,0 5.672.614,8 108.000 100.000.000 15,253
Edad
Hasta 24 años 3.225 1.090.170,3 756.663,3 10.000 14.620.000 13,664
25 a 34 años 7.163 1.575.684,4 1.516.309,8 5.000 30.000.000 13,985
35 a 44 años 6.844 1.799.162,2 2.565.308,8 50 87.860.000 13,994
45 a 54 años 5.439 1.718.625,1 2.975.141,8 80 100.000.000 13,917
55 a 64 años 3.921 1.641.687,4 2.493.514,9 60 74.000.000 13,785
65 años o más 1.680 1.302.738,9 3.261.522,8 8.000 93.000.000 13,379
Horas trabajadas a la semana
Hasta 30 horas 4.329 811.622,6 1.917.911,6 80 93.000.000 12,936
31 a 48 horas 17.721 1.779.921,4 2.276.243,7 10.000 100.000.000 14,072
Más de 48 horas 6.222 1.612.608,9 2.661.319,8 50 90.000.000 13,962
Meses en el trabajo
Hasta 12 meses 8.756 1.298.707,3 1.360.628,0 5.000 30.000.000 13,743
13 a 60 meses 9.727 1.519.588,1 1.908.521,1 50 90.000.000 13,883
Más de 60 meses 9.789 1.934.481,4 3.219.765,2 60 100.000.000 13,981
Total muestra 28.272 1.594.834,2 2.341.943,7 50 100.000.000 13,874
Fuente: Elaboración propia con base en microdatos GEIH DANE.

El ingreso laboral en Colombia para febrero de 2024, nos evidencia un ingreso laboral en promedio de $1.594.834. No obstante, este promedio presenta una alta dispersión, por lo que la predicción es dificil, por el hecho de que hay personas con características similares que tienen ingresos muy distintos.

Aun asi entre las variables analizadas, existen características que evidencian los niveles de ingreso. El nivel de educación es la muestra que representa una diferencia marcada dentro del ingreso.Puesto que las personas con primaria o menos tienen un ingreso promedio de $835.340, mientras que quienes poseen un posgrado su ingreso asciende a $5.411.166, es decir 6,5 veces el ingreso que reciben quienes tienen primaria o menos.

A lo anterior se suman, las diferencias relacionadas con la edad, las diferencias entre hombres y mujeres y el numero de horas trabajadas entre semana. Todo esto, en conjunto, muestra que el ingreso laboral esta asocidado a diversas caracteristicas individuales y laborales, siendo el nivel educativo el que hace la diferencia dentro del análisis.

3.2 Variables Explicativas Cuantitativas

3.2.1 Edad

La edad es medida en años tal como la reporta la Gran Encuesta Integrada de Hogares (GEIH) de 2024, para el mes de febrero. La Tabla 3 resume las estadísticas descriptivas por sexo.

resumen_edad <- function(df, var) {
  df %>%
    group_by(Categoria = {{ var }}) %>%
    summarise(
      N        = n(),
      Promedio = round(mean(edad, na.rm = TRUE), 1),
      Desv     = round(sd(edad, na.rm = TRUE), 2),
      Minimo   = min(edad, na.rm = TRUE),
      Maximo   = max(edad, na.rm = TRUE),
      .groups  = "drop"
    ) %>%
    mutate(Categoria = as.character(Categoria))
}

total_edad <- df_modelo %>%
  summarise(
    Categoria = "Total muestra",
    N        = n(),
    Promedio = round(mean(edad, na.rm = TRUE), 1),
    Desv     = round(sd(edad, na.rm = TRUE), 2),
    Minimo   = min(edad, na.rm = TRUE),
    Maximo   = max(edad, na.rm = TRUE)
  )

tabla_promedios_edad <- bind_rows(
  resumen_edad(df_modelo, sexo),
  total_edad
)

tabla_promedios_edad %>%
  kbl(
    caption = "Tabla 5. Estadísticas descriptivas de la edad según el sexo",
    align = c("l", "r", "r", "r", "r", "r"),
    col.names = c("Categoría", "N", "Edad promedio", "Desv. Estándar", "Mínimo", "Máximo"),
    format.args = list(big.mark = ".", decimal.mark = ",")
  ) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed"),
    full_width = FALSE,
    font_size = 14,
    position = "center"
  ) %>%
  row_spec(0, background = "#7A1F2B", color = "#FFFFFF", bold = TRUE) %>%
  column_spec(1, bold = TRUE, width = "4cm") %>%
  column_spec(2:6, width = "2.8cm") %>%
  column_spec(3, bold = TRUE, background = "#FDF0F0", color = "#7A1F2B") %>%
  row_spec(3, bold = TRUE, background = "#F9F3E3", color = "#7A1F2B") %>%
  footnote(
    general = "Elaboración propia con base en microdatos GEIH DANE.",
    general_title = "Fuente:",
    footnote_as_chunk = TRUE
  )
Tabla 5. Estadísticas descriptivas de la edad según el sexo
Categoría N Edad promedio Desv. Estándar Mínimo Máximo
Hombre 15.804 41,7 14,37 15 93
Mujer 12.468 40,8 13,20 15 88
Total muestra 28.272 41,3 13,87 15 93
Fuente: Elaboración propia con base en microdatos GEIH DANE.

Con los datos de la Tabla 3, se evidencia que el rango de edad de la muestra esta entre los 15 y 93 años, con una edad promedio de 41 años; en donde hombres (41,7años ) y mujeres (40,8 años) tienen edades en promedio muy similares, por lo que se ausme que la edad aporta información sobre el ingreso, independiente de la diferencia entre sexos.

Dispersion_edad1 <- ggplot(df_modelo, aes(x = edad, y = ln_ingreso)) +
  geom_point(
    color = "#C7A64A",
    alpha = 0.25,
    size = 1.8
  ) +
  geom_smooth(
    method = "lm",
    formula = y ~ x + I(x^2),
    color = "#D90429",
    fill = "#FDF0F0",
    alpha = 0.6,
    linewidth = 1.2,
    se = TRUE
  ) +
  scale_x_continuous(
    name = "Edad (años)",
    breaks = seq(10, 90, by = 10)
  ) +
  scale_y_continuous(
    name = "Ln(ingreso laboral mensual)"
  ) +
  labs(
    title = "Figura 2. RELACIÓN ENTRE LA EDAD Y EL INGRESO LABORAL",
    subtitle = "Transformación logarítmica aplicada al ingreso | Curva de tendencia cuadrática",
    caption = "Fuente: Elaboración propia con base en microdatos GEIH DANE"
  ) +
  theme_minimal(base_size = 13, base_family = "Georgia") +
  theme(
    plot.title = element_text(
      face = "bold", size = 13, hjust = 0.5,
      margin = margin(b = 6), color = "#7A1F2B"
    ),
    plot.subtitle = element_text(
      size = 10.5, hjust = 0.5, color = "#2B2D42",
      margin = margin(b = 15)
    ),
    plot.caption = element_text(
      size = 9, color = "#6C757D", hjust = 0.5,
      face = "italic", margin = margin(t = 12)
    ),
    axis.title = element_text(face = "bold", size = 11, color = "#2B2D42"),
    axis.text = element_text(size = 9.5, color = "#2B2D42"),
    panel.grid.major = element_line(color = "#E8E4E1", linewidth = 0.4),
    panel.grid.minor = element_blank(),
    plot.margin = margin(15, 15, 15, 15)
  )

print(Dispersion_edad1)

En la figura 2 encontramos una linea de tendencia que nos indica que a mayor edad el ingreso tiende a ser mas alto. Sin embargo, los puntos de la grafica se distribuyen de manera muy amplia alrededor de la linea de tendencia, es decir, que personas de la misma edad tienen ingresos muy distintos.

3.2.2 Edad al Cuadrado

Dado que la edad y el ingreso no es lineal, se incorpora la edad al cuadrado como un predictor adicional.

df_sq <- df_modelo %>%
  mutate(edad_sq = edad^2)

resumen_edad_sq <- function(df, var) {
  df %>%
    group_by(Categoria = {{ var }}) %>%
    summarise(
      N        = n(),
      Promedio = round(mean(edad_sq, na.rm = TRUE), 1),
      Desv     = round(sd(edad_sq, na.rm = TRUE), 1),
      Minimo   = min(edad_sq, na.rm = TRUE),
      Maximo   = max(edad_sq, na.rm = TRUE),
      .groups  = "drop"
    ) %>%
    mutate(Categoria = as.character(Categoria))
}

total_edad_sq <- df_sq %>%
  summarise(
    Categoria = "Total muestra",
    N        = n(),
    Promedio = round(mean(edad_sq, na.rm = TRUE), 1),
    Desv     = round(sd(edad_sq, na.rm = TRUE), 1),
    Minimo   = min(edad_sq, na.rm = TRUE),
    Maximo   = max(edad_sq, na.rm = TRUE)
  )

tabla_edad_sq <- bind_rows(
  resumen_edad_sq(df_sq, sexo),
  total_edad_sq
)

tabla_edad_sq %>%
  kbl(
    caption = "Tabla 6. Estadísticas descriptivas de la edad al cuadrado según el sexo",
    align = c("l", "r", "r", "r", "r", "r"),
    col.names = c("Categoría", "N", "Edad² promedio", "Desv. Estándar", "Mínimo", "Máximo"),
    format.args = list(big.mark = ".", decimal.mark = ",")
  ) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed"),
    full_width = FALSE,
    font_size = 14,
    position = "center"
  ) %>%
  row_spec(0, background = "#7A1F2B", color = "#FFFFFF", bold = TRUE) %>%
  column_spec(1, bold = TRUE, width = "4cm") %>%
  column_spec(2:6, width = "2.8cm") %>%
  column_spec(3, bold = TRUE, background = "#FDF0F0", color = "#7A1F2B") %>%
  row_spec(3, bold = TRUE, background = "#F9F3E3", color = "#7A1F2B") %>%
  footnote(
    general = "Elaboración propia con base en microdatos GEIH DANE.",
    general_title = "Fuente:",
    footnote_as_chunk = TRUE
  )
Tabla 6. Estadísticas descriptivas de la edad al cuadrado según el sexo
Categoría N Edad² promedio Desv. Estándar Mínimo Máximo
Hombre 15.804 1.948,3 1.292,8 225 8.649
Mujer 12.468 1.840,2 1.162,2 225 7.744
Total muestra 28.272 1.900,7 1.238,1 225 8.649
Fuente: Elaboración propia con base en microdatos GEIH DANE.

Los datos observados en la tabla 4 acerca de la edad al cuadrado, nos evidencia unos valores mucho mas grande que la edad, pero su distribución por sexo es similar.La edad al cuadrado permite que nuestro modelo refleje como el ingreso esperado aumenta con la edad hasta cierto punto y luego disminuye, lo que nos resulta mejor frente a usar solo la edad.

Dispersion_edad2 <- ggplot(df_modelo, aes(x = edad^2, y = ln_ingreso)) +
  geom_point(
    color = "#C7A64A",
    alpha = 0.25,
    size = 1.8
  ) +
  geom_smooth(
    method = "lm",
    formula = y ~ x + I(x^2),
    color = "#D90429",
    fill = "#FDF0F0",
    alpha = 0.6,
    linewidth = 1.2,
    se = TRUE
  ) +
  scale_x_continuous(
    name = "Edad al cuadrado",
    labels = function(x) format(x, big.mark = ".")
  ) +
  scale_y_continuous(
    name = "Ln(ingreso laboral mensual)"
  ) +
  labs(
    title = "Figura 3. RELACIÓN ENTRE LA EDAD AL CUADRADO Y EL INGRESO LABORAL",
    subtitle = "Transformación logarítmica aplicada al ingreso | Curva de tendencia cuadrática",
    caption = "Fuente: Elaboración propia con base en microdatos GEIH DANE"
  ) +
  theme_minimal(base_size = 13, base_family = "Georgia") +
  theme(
    plot.title = element_text(
      face = "bold", size = 13, hjust = 0.5,
      margin = margin(b = 6), color = "#7A1F2B"
    ),
    plot.subtitle = element_text(
      size = 10.5, hjust = 0.5, color = "#2B2D42",
      margin = margin(b = 15)
    ),
    plot.caption = element_text(
      size = 9, color = "#6C757D", hjust = 0.5,
      face = "italic", margin = margin(t = 12)
    ),
    axis.title = element_text(face = "bold", size = 11, color = "#2B2D42"),
    axis.text = element_text(size = 9.5, color = "#2B2D42"),
    panel.grid.major = element_line(color = "#E8E4E1", linewidth = 0.4),
    panel.grid.minor = element_blank(),
    plot.margin = margin(15, 15, 15, 15)
  )

print(Dispersion_edad2)

A partir de el gráfico se infiere que esta variable nos ayuda a probar que el ingreso aumenta con la edad hasta cierto punto y despues se estabiliza o disminuye.

3.2.3 Horas trabajadas a la semana

Las horas trabajadas a la semana miden la intensidad de la jornada laboral.

resumen_horas <- function(df, var) {
  df %>%
    group_by(Categoria = {{ var }}) %>%
    summarise(
      N        = n(),
      Promedio = round(mean(horas_semana, na.rm = TRUE), 1),
      Desv     = round(sd(horas_semana, na.rm = TRUE), 2),
      Minimo   = min(horas_semana, na.rm = TRUE),
      Maximo   = max(horas_semana, na.rm = TRUE),
      .groups  = "drop"
    ) %>%
    mutate(Categoria = as.character(Categoria))
}

total_horas <- df_modelo %>%
  summarise(
    Categoria = "Total muestra",
    N        = n(),
    Promedio = round(mean(horas_semana, na.rm = TRUE), 1),
    Desv     = round(sd(horas_semana, na.rm = TRUE), 2),
    Minimo   = min(horas_semana, na.rm = TRUE),
    Maximo   = max(horas_semana, na.rm = TRUE)
  )

tabla_promedios_horas <- bind_rows(
  resumen_horas(df_modelo, sexo),
  total_horas
)

tabla_promedios_horas %>%
  kbl(
    caption = "Tabla 7. Estadísticas descriptivas de las horas trabajadas a la semana según el sexo",
    align = c("l", "r", "r", "r", "r", "r"),
    col.names = c("Categoría", "N", "Horas promedio trabajadas", "Desv. Estándar", "Mínimo", "Máximo"),
    format.args = list(big.mark = ".", decimal.mark = ",")
  ) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed"),
    full_width = FALSE,
    font_size = 14,
    position = "center"
  ) %>%
  row_spec(0, background = "#7A1F2B", color = "#FFFFFF", bold = TRUE) %>%
  column_spec(1, bold = TRUE, width = "4cm") %>%
  column_spec(2:6, width = "2.8cm") %>%
  column_spec(3, bold = TRUE, background = "#FDF0F0", color = "#7A1F2B") %>%
  row_spec(3, bold = TRUE, background = "#F9F3E3", color = "#7A1F2B") %>%
  footnote(
    general = "Elaboración propia con base en microdatos GEIH DANE.",
    general_title = "Fuente:",
    footnote_as_chunk = TRUE
  )
Tabla 7. Estadísticas descriptivas de las horas trabajadas a la semana según el sexo
Categoría N Horas promedio trabajadas Desv. Estándar Mínimo Máximo
Hombre 15.804 46,9 11,85 2 130
Mujer 12.468 41,3 14,00 1 120
Total muestra 28.272 44,5 13,14 1 130
Fuente: Elaboración propia con base en microdatos GEIH DANE.

Las horas trabajadas a la semana nos demuestran la intensidad de la jornada laboral de las personas de la muestra. En promedio las personas trabajan 44,5 horas a la semana, ademas existe una diferencia entre hombres y mujeres, donde el hombre trabaja 5,6 horas mas, los cual se vuelve relevante para el ingreso laboral, pues quien trabaja menos tiende a ganar menos y quien trabaja mas, tiende a ganar mas.

Dispersion_horas <- ggplot(df_modelo, aes(x = horas_semana, y = ln_ingreso)) +
  geom_point(
    color = "#C7A64A",
    alpha = 0.25,
    size = 1.8
  ) +
  geom_smooth(
    method = "lm",
    formula = y ~ x,
    color = "#D90429",
    fill = "#FDF0F0",
    alpha = 0.6,
    linewidth = 1.2,
    se = TRUE
  ) +
  scale_x_continuous(
    name = "Horas trabajadas a la semana",
    breaks = seq(0, 100, by = 10)
  ) +
  scale_y_continuous(
    name = "Ln(ingreso laboral mensual)"
  ) +
  labs(
    title = "Figura 4. RELACIÓN ENTRE LAS HORAS TRABAJADAS Y EL INGRESO LABORAL",
    subtitle = "Transformación logarítmica aplicada al ingreso | Tendencia lineal",
    caption = "Fuente: Elaboración propia con base en microdatos GEIH DANE"
  ) +
  theme_minimal(base_size = 13, base_family = "Georgia") +
  theme(
    plot.background = element_rect(fill = "white", color = NA),
    panel.background = element_rect(fill = "white", color = NA),
    plot.title = element_text(
      face = "bold", size = 13, hjust = 0.5,
      margin = margin(b = 6), color = "#7A1F2B"
    ),
    plot.subtitle = element_text(
      size = 10.5, hjust = 0.5, color = "#2B2D42",
      margin = margin(b = 15)
    ),
    plot.caption = element_text(
      size = 9, color = "#6C757D", hjust = 0.5,
      face = "italic", margin = margin(t = 12)
    ),
    axis.title = element_text(face = "bold", size = 11, color = "#2B2D42"),
    axis.text = element_text(size = 9.5, color = "#2B2D42"),
    panel.grid.major = element_line(color = "#E8E4E1", linewidth = 0.4),
    panel.grid.minor = element_blank(),
    plot.margin = margin(15, 15, 15, 15)
  )

print(Dispersion_horas)

La linea de tendencia nos muestra que existe una concentración de puntos cerca de las 40 a 48 horas, es decir, que compete con lo que esta esblecido para una jornada laboral, pero también hay personas con ingresos muy bajos incluso teniendo jornadas laborales muy largas. Demostrando que trabajar mas horas si esta asociado con mayores ingresos, pero no los garantiza.

3.2.4 Meses trabajados

Los meses en el trabajo miden la antiguedad de la persona en su empleo actual.

resumen_meses <- function(df, var) {
  df %>%
    group_by(Categoria = {{ var }}) %>%
    summarise(
      N        = n(),
      Promedio = round(mean(meses_trabajo, na.rm = TRUE), 1),
      Desv     = round(sd(meses_trabajo, na.rm = TRUE), 2),
      Minimo   = min(meses_trabajo, na.rm = TRUE),
      Maximo   = max(meses_trabajo, na.rm = TRUE),
      .groups  = "drop"
    ) %>%
    mutate(Categoria = as.character(Categoria))
}

total_meses <- df_modelo %>%
  summarise(
    Categoria = "Total muestra",
    N        = n(),
    Promedio = round(mean(meses_trabajo, na.rm = TRUE), 1),
    Desv     = round(sd(meses_trabajo, na.rm = TRUE), 2),
    Minimo   = min(meses_trabajo, na.rm = TRUE),
    Maximo   = max(meses_trabajo, na.rm = TRUE)
  )

tabla_promedios_meses <- bind_rows(
  resumen_meses(df_modelo, sexo),
  total_meses
)

tabla_promedios_meses %>%
  kbl(
    caption = "Tabla 8. Estadísticas descriptivas de los meses en el trabajo según el sexo",
    align = c("l", "r", "r", "r", "r", "r"),
    col.names = c("Categoría", "N", "Meses promedio en el trabajo", "Desv. Estándar", "Mínimo", "Máximo"),
    format.args = list(big.mark = ".", decimal.mark = ",")
  ) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed"),
    full_width = FALSE,
    font_size = 14,
    position = "center"
  ) %>%
  row_spec(0, background = "#7A1F2B", color = "#FFFFFF", bold = TRUE) %>%
  column_spec(1, bold = TRUE, width = "4cm") %>%
  column_spec(2:6, width = "2.8cm") %>%
  column_spec(3, bold = TRUE, background = "#FDF0F0", color = "#7A1F2B") %>%
  row_spec(3, bold = TRUE, background = "#F9F3E3", color = "#7A1F2B") %>%
  footnote(
    general = "Elaboración propia con base en microdatos GEIH DANE.",
    general_title = "Fuente:",
    footnote_as_chunk = TRUE
  )
Tabla 8. Estadísticas descriptivas de los meses en el trabajo según el sexo
Categoría N Meses promedio en el trabajo Desv. Estándar Mínimo Máximo
Hombre 15.804 93,7 119,43 0 840
Mujer 12.468 70,5 98,56 0 732
Total muestra 28.272 83,5 111,31 0 840
Fuente: Elaboración propia con base en microdatos GEIH DANE.

La distribución de meses trabajados muestra una asimetria positiva, con una desviación estandar de 111,31 meses, superando al promedio (83,5) lo cual indica una gran variedad de antiguedades,desde personas que acaban de empezar hasta otras con muchos años en el mismo empleo.Ademas la mayor parte se encuentra en antiguedades bajas con 12 meses o menos y esto es tanto en hombres como en mujeres, aunque los hombres de la muestra tienen en promedio mas antiguedad en sus empleos.

Dispersion_meses <- ggplot(df_modelo, aes(x = meses_trabajo, y = ln_ingreso)) +
  geom_point(
    color = "#C7A64A",
    alpha = 0.25,
    size = 1.8
  ) +
  geom_smooth(
    method = "lm",
    formula = y ~ x,
    color = "#D90429",
    fill = "#FDF0F0",
    alpha = 0.6,
    linewidth = 1.2,
    se = TRUE
  ) +
  scale_x_continuous(
    name = "Meses en el trabajo",
    labels = function(x) format(x, big.mark = ".", decimal.mark = ",")
  ) +
  scale_y_continuous(
    name = "Ln(ingreso laboral mensual)"
  ) +
  labs(
    title = "Figura 5. RELACIÓN ENTRE LOS MESES EN EL TRABAJO Y EL INGRESO LABORAL",
    subtitle = "Transformación logarítmica aplicada al ingreso | Tendencia lineal",
    caption = "Fuente: Elaboración propia con base en microdatos GEIH DANE"
  ) +
  theme_minimal(base_size = 13, base_family = "Georgia") +
  theme(
    plot.background = element_rect(fill = "white", color = NA),
    panel.background = element_rect(fill = "white", color = NA),
    plot.title = element_text(
      face = "bold", size = 13, hjust = 0.5,
      margin = margin(b = 6), color = "#7A1F2B"
    ),
    plot.subtitle = element_text(
      size = 10.5, hjust = 0.5, color = "#2B2D42",
      margin = margin(b = 15)
    ),
    plot.caption = element_text(
      size = 9, color = "#6C757D", hjust = 0.5,
      face = "italic", margin = margin(t = 12)
    ),
    axis.title = element_text(face = "bold", size = 11, color = "#2B2D42"),
    axis.text = element_text(size = 9.5, color = "#2B2D42"),
    panel.grid.major = element_line(color = "#E8E4E1", linewidth = 0.4),
    panel.grid.minor = element_blank(),
    plot.margin = margin(15, 15, 15, 15)
  )

print(Dispersion_meses)

3.3 Variables Explicativas Cualitativas

3.3.1 Sexo

El sexo de las personas de la muestra se incluye como predictor categórico.

tabla_resultados_sexo <- df_modelo %>%
  group_by(sexo) %>%
  summarise(Frecuencia = n(), .groups = "drop") %>%
  arrange(desc(Frecuencia)) %>%
  mutate(
    sexo = as.character(sexo),
    Porcentaje = round((Frecuencia / sum(Frecuencia)) * 100, 1),
    Porcentaje_Acumulado = cumsum(Porcentaje)
  )

tabla_resultados_sexo %>%
  kable(
    format = "html",
    col.names = c("Sexo", "Frecuencia", "Porcentaje (%)", "Porcentaje acumulado (%)"),
    align = c("l", "c", "c", "c"),
    caption = "Tabla 9. Distribución de frecuencias del sexo de las personas de la muestra",
    format.args = list(big.mark = ".", decimal.mark = ",")
  ) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed"),
    full_width = FALSE,
    font_size = 14,
    position = "center"
  ) %>%
  row_spec(0, background = "#7A1F2B", color = "#FFFFFF", bold = TRUE) %>%
  column_spec(1, bold = TRUE, color = "#7A1F2B", width = "3.5cm") %>%
  column_spec(2, bold = TRUE, background = "#FDF0F0", color = "#7A1F2B", width = "3cm") %>%
  column_spec(3:4, width = "3cm") %>%
  footnote(
    general = "Elaboración propia con base en microdatos GEIH DANE",
    general_title = "Fuente:",
    footnote_as_chunk = TRUE
  )
Tabla 9. Distribución de frecuencias del sexo de las personas de la muestra
Sexo Frecuencia Porcentaje (%) Porcentaje acumulado (%)
Hombre 15.804 55,9 55,9
Mujer 12.468 44,1 100,0
Fuente: Elaboración propia con base en microdatos GEIH DANE

La tabla 7 nos revela como esta distribuida nuestra muestra según el sexo; de la 28.272 personas, el 55,9% son hombres y el 44,1% son mujeres.Es decir que la muestra esta relativamente equilibrada,aunque hay una mayor proporción de hombres que de mujeres.

La Figura 6 muestra cómo se distribuye el logaritmo del ingreso laboral mensual según el sexo.

library(dplyr)
library(plotly)

df_modelo_sexo <- df_modelo %>%
  group_by(sexo) %>%
  mutate(
    mediana_ln = median(ln_ingreso, na.rm = TRUE),
    q1_ln = quantile(ln_ingreso, 0.25, na.rm = TRUE),
    q3_ln = quantile(ln_ingreso, 0.75, na.rm = TRUE),
    mediana_ingreso = median(ingreso, na.rm = TRUE)
  ) %>%
  ungroup()

boxplot_sexo <- plot_ly(
  data = df_modelo_sexo,
  x = ~sexo,
  y = ~ln_ingreso,
  color = ~sexo,
  colors = c("#7A1F2B", "#C7A64A"),
  type = "box",
  boxpoints = "outliers",
  pointpos = 0,
  hoverinfo = "text",
  hovertext = ~paste(
    "<b>Sexo:</b>", sexo,
    "<br><b>Mediana Ln(Ingreso):</b>", round(mediana_ln, 2),
    "<br><b>Mediana Ingreso:</b> $", format(round(mediana_ingreso), big.mark = ".", decimal.mark = ","),
    "<br><b>Cuartil 1 (Q1):</b>", round(q1_ln, 2),
    "<br><b>Cuartil 3 (Q3):</b>", round(q3_ln, 2),
    "<br>-----------------------------",
    "<br><b>Ln(Ingreso obs.):</b>", round(ln_ingreso, 2),
    "<br><b>Ingreso obs.:</b> $", format(round(ingreso), big.mark = ".", decimal.mark = ",")
  ),
  marker = list(
    size = 4,
    color = "#7A1F2B",
    line = list(width = 0.5, color = "#430404")
  ),
  line = list(width = 0.8),
  width = 0.7
) %>%
  layout(
    title = list(
      text = "<b>Figura 6. </b><br><sub>RELACIÓN ENTRE EL SEXO Y EL INGRESO LABORAL MENSUAL</sub>",
      x = 0.5,
      xanchor = "center",
      font = list(size = 18, color = "#7A1F2B")
    ),
    xaxis = list(
      title = "<b>Sexo</b>",
      tickfont = list(size = 12)
    ),
    yaxis = list(
      title = "<b>Ln(Ingreso laboral mensual)</b>",
      tickfont = list(size = 11)
    ),
    showlegend = FALSE,
    hoverlabel = list(
      bgcolor = "#FCFAF8",
      bordercolor = "#C7A64A",
      font = list(size = 12)
    ),
    margin = list(l = 60, r = 40, t = 100, b = 100),
    annotations = list(
      list(
        x = 1,
        y = -0.3,
        text = "Fuente: Elaboración propia con base en microdatos GEIH DANE",
        xref = "paper",
        yref = "paper",
        xanchor = "right",
        yanchor = "auto",
        showarrow = FALSE,
        font = list(size = 10, color = "gray50")
      )
    )
  )

boxplot_sexo

A partir del diagrama de cajas, se obtiene que las medianas de ambos grupos son similares, alrededor de 14.Esto nos demuestra que por si solo el sexo de las personas, no separa de forma marcada el ingreso laboral; pues ambos presentan valores atipicos, es decir, que hay personas con ingresos anormalmente altos y bajos, por lo que la diferencia entre sexos es pequeña frente a la variabilidad que existe dentro de cada grupo.

3.3.2 Nivel educativo

El nivel educativo se agrupa en cinco categorias y se incluye como predictor categórico.

tabla_resultados_educ <- df_modelo %>%
  group_by(nivel_educ_grupo) %>%
  summarise(Frecuencia = n(), .groups = "drop") %>%
  arrange(nivel_educ_grupo) %>%
  mutate(
    nivel_educ_grupo = as.character(nivel_educ_grupo),
    Porcentaje = round((Frecuencia / sum(Frecuencia)) * 100, 1),
    Porcentaje_Acumulado = cumsum(Porcentaje)
  )

tabla_resultados_educ %>%
  kable(
    format = "html",
    col.names = c("Nivel educativo", "Frecuencia", "Porcentaje (%)", "Porcentaje acumulado (%)"),
    align = c("l", "c", "c", "c"),
    caption = "Tabla 10. Distribución de frecuencias del nivel educativo de las personas de la muestra",
    format.args = list(big.mark = ".", decimal.mark = ",")
  ) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed"),
    full_width = FALSE,
    font_size = 14,
    position = "center"
  ) %>%
  row_spec(0, background = "#7A1F2B", color = "#FFFFFF", bold = TRUE) %>%
  column_spec(1, bold = TRUE, color = "#7A1F2B", width = "5cm") %>%
  column_spec(2, bold = TRUE, background = "#FDF0F0", color = "#7A1F2B", width = "2.5cm") %>%
  column_spec(3:4, width = "3cm") %>%
  footnote(
    general = "Elaboración propia con base en microdatos GEIH DANE. Categoría de referencia: Primaria o menos.",
    general_title = "Fuente:",
    footnote_as_chunk = TRUE
  )
Tabla 10. Distribución de frecuencias del nivel educativo de las personas de la muestra
Nivel educativo Frecuencia Porcentaje (%) Porcentaje acumulado (%)
Primaria o menos 5.710 20,2 20,2
Secundaria / Media 12.719 45,0 65,2
Técnica / Tecnológica 3.809 13,5 78,7
Universitaria 4.416 15,6 94,3
Posgrado 1.618 5,7 100,0
Fuente: Elaboración propia con base en microdatos GEIH DANE. Categoría de referencia: Primaria o menos.

La distribución se concentra en los niveles intermedios. La secundaria o media agrupa la mayor parte de la muestra, con 12.719 personas, seguida de primaria o menos con 5.710 y universitaria con 4.416. El nivel técnico o tecnológico reúne 3.809 personas y posgrado es el grupo más reducido, con 1.618.

df_modelo_educ <- df_modelo %>%
  group_by(nivel_educ_grupo) %>%
  mutate(
    mediana_ln = median(ln_ingreso, na.rm = TRUE),
    q1_ln = quantile(ln_ingreso, 0.25, na.rm = TRUE),
    q3_ln = quantile(ln_ingreso, 0.75, na.rm = TRUE),
    mediana_ingreso = median(ingreso, na.rm = TRUE)
  ) %>%
  ungroup()

boxplot_educ_interactivo <- plot_ly(
  data = df_modelo_educ,
  x = ~nivel_educ_grupo,
  y = ~ln_ingreso,
  color = ~nivel_educ_grupo,
  colors = c("#D98A94", "#B84050", "#9E2A3B", "#7A1F2B", "#C7A64A"),
  type = "box",
  boxpoints = "outliers",
  pointpos = 0,
  hoverinfo = "text",
  hovertext = ~paste(
    "<b>Nivel educativo:</b>", nivel_educ_grupo,
    "<br><b>Mediana Ln(Ingreso):</b>", round(mediana_ln, 2),
    "<br><b>Mediana Ingreso:</b> $", format(round(mediana_ingreso), big.mark = ".", decimal.mark = ","),
    "<br><b>Cuartil 1 (Q1):</b>", round(q1_ln, 2),
    "<br><b>Cuartil 3 (Q3):</b>", round(q3_ln, 2),
    "<br>-----------------------------",
    "<br><b>Ln(Ingreso obs.):</b>", round(ln_ingreso, 2),
    "<br><b>Ingreso obs.:</b> $", format(round(ingreso), big.mark = ".", decimal.mark = ",")
  ),
  marker = list(
    size = 4,
    color = "#7A1F2B",
    line = list(width = 0.5, color = "#430404")
  ),
  line = list(width = 0.8, color = "#7A1F2B")
) %>%
  layout(
    title = list(
      text = "<b>Figura 7. </b><br><sub>RELACIÓN ENTRE EL NIVEL EDUCATIVO Y EL INGRESO LABORAL MENSUAL</sub>",
      x = 0.5,
      xanchor = "center",
      font = list(size = 18, color = "#7A1F2B")
    ),
    xaxis = list(
      title = list(text = "<b>Nivel educativo</b>", standoff = 10),
      tickangle = -30,
      tickfont = list(size = 12)
    ),
    yaxis = list(
      title = "<b>Ln(Ingreso laboral mensual)</b>",
      tickfont = list(size = 11)
    ),
    showlegend = FALSE,
    hoverlabel = list(
      bgcolor = "#FCFAF8",
      bordercolor = "#C7A64A",
      font = list(size = 12)
    ),
    margin = list(l = 60, r = 40, t = 100, b = 140),
    annotations = list(
      list(
        x = 1,
        y = -0.5,
        text = "Fuente: Elaboración propia con base en microdatos GEIH DANE",
        xref = "paper",
        yref = "paper",
        xanchor = "right",
        yanchor = "auto",
        showarrow = FALSE,
        font = list(size = 10, color = "gray50")
      )
    )
  )

boxplot_educ_interactivo

La mediana del logaritmo del ingreso aumenta con cada nivel educativo, con el mayor salto hacia posgrado. Esto coincide con la Tabla 2, donde el ingreso promedio pasa de $835.340 a $5.411.166, evidenciando que el nivel educativo es probablemente el predictor más informativo nuestra muestra.

4. Estimación del modelo de regresión múltiple

Para analizar las determinantes socioeconómicas y laborales del ingreso individual en Colombia, se estimó un modelo de regresión lineal múltiple mediante Mínimos Cuadrados Ordinarios (MCO) a partir de los microdatos de la Gran Encuesta Integrada de Hogares (GEIH - DANE). La variable dependiente utilizada corresponde al logaritmo natural del ingreso laboral (\(\ln(\text{Ingreso})\)), lo que permite interpretar los coeficientes estimados como variaciones porcentuales aproximadas en el ingreso ante cambios unitarios en las variables cuantitativas o comparaciones respecto a categorías base en las variables categóricas[cite: 18]. La ecuación del modelo poblacional se especifica de la siguiente manera:

\[ \begin{aligned} \ln(\text{Ingreso}_i) = \beta_0 &+ \beta_1 \text{Sexo Mujer}_i + \beta_2 \text{Educ Secundaria}_i + \beta_3 \text{Educ Técnica}_i \\ &+ \beta_4 \text{Educ Universitaria}_i + \beta_5 \text{Educ Posgrado}_i + \beta_6 \text{Edad}_i \\ &+ \beta_7 \text{Edad}_i^2 + \beta_8 \text{Horas Semana}_i + \beta_9 \text{Meses Trabajo}_i + \varepsilon_i \end{aligned} \]

library(broom)     

if(!("edad_sq" %in% names(df_modelo))) {
  df_modelo <- df_modelo %>% mutate(edad_sq = edad^2)
}

modelo_reg <- lm(ln_ingreso ~ sexo + nivel_educ_grupo + edad + edad_sq + horas_semana + meses_trabajo, data = df_modelo)

resumen_mod <- tidy(modelo_reg) %>%
  mutate(
    term = case_when(
      term == "sexoMujer" ~ "Sexo_Mujer",
      term == "nivel_educ_grupoSecundaria / Media" ~ "NiEduc_Sec/Med",
      term == "nivel_educ_grupoTécnica / Tecnológica" ~ "NiEduc_Tecni/Tecno",
      term == "nivel_educ_grupoUniversitaria" ~ "NiEduc_Univ",
      term == "nivel_educ_grupoPosgrado" ~ "NiEduc_Posgrado",
      term == "edad" ~ "Edad",
      term == "edad_sq" ~ "Edad²",
      term == "horas_semana" ~ "Horas_Semana",
      term == "meses_trabajo" ~ "(Antiguedad) Meses_Trabajo",
      term == "(Intercept)" ~ "Intercepto",
      TRUE ~ term
    )
  ) %>%
  mutate(across(where(is.numeric), ~ round(., 5))) %>%
  rename(
    `Variable` = term,
    `Coeficiente` = estimate,
    `Error Estándar` = std.error,
    `Estadístico t` = statistic,
    `Valor p` = p.value
  ) %>%
  mutate(
    Significancia = case_when(
      `Valor p` < 0.001 ~ "***",
      `Valor p` < 0.01  ~ "**",
      `Valor p` < 0.05  ~ "*",
      `Valor p` < 0.1   ~ ".",
      TRUE ~ ""
    ),
    `Valor p formateado` = case_when(
      is.na(`Valor p`) ~ "NA",
      `Valor p` < 0.0001 ~ "< 0.0001",
      TRUE ~ sprintf("%.4f", `Valor p`)
    )
  )

resumen_global <- glance(modelo_reg)

R2 <- round(resumen_global$adj.r.squared, 4)
Fstat <- round(resumen_global$statistic, 2)
pvalor_modelo <- ifelse(resumen_global$p.value < 0.0001, 
                        "< 0.0001", 
                        sprintf("%.4f", resumen_global$p.value))
N <- resumen_global$nobs

filas_resumen <- tibble(
  Variable = c("R² ajustado", "F", "Valor p (modelo)", "N"),
  Coeficiente = as.character(c(R2, Fstat, pvalor_modelo, N)),
  `Error Estándar` = "",
  `Estadístico t` = "",
  `Valor p formateado` = "",
  Significancia = ""
)

tabla_principal <- resumen_mod %>%
  select(Variable, Coeficiente, `Error Estándar`, `Estadístico t`, 
         `Valor p formateado`, Significancia) %>%
  mutate(across(everything(), as.character))

tabla_final <- bind_rows(tabla_principal, filas_resumen)

names(tabla_final) <- c("Variable", "Coeficiente", "Error Estándar", 
                        "Estadístico t", "Valor p", "Sig.")

kbl(tabla_final,
    caption = "Tabla 11. Resultados del modelo de regresión lineal múltiple (Ln Ingreso Laboral)",
    align = c("l", "r", "r", "r", "r", "c"),
    col.names = names(tabla_final)) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
                full_width = FALSE,
                font_size = 14,
                position = "center") %>%
  row_spec(0, background = "#7A1F2B", color = "#FFFFFF", bold = TRUE) %>%
  column_spec(1, bold = TRUE, color = "#2B2D42", width = "5cm") %>%
  column_spec(2, bold = TRUE, background = "#FDF0F0", color = "#7A1F2B", width = "2.8cm") %>%
  column_spec(3:5, width = "2.5cm") %>%
  column_spec(6, bold = TRUE, color = "#7A1F2B", width = "1.5cm") %>%
  row_spec((nrow(tabla_principal) + 1):nrow(tabla_final),
           bold = TRUE, italic = FALSE, background = "#F9F3E3", color = "#7A1F2B") %>%
  footnote(
    general = "Elaboración propia con base en microdatos GEIH DANE. Variable dependiente: Logaritmo natural del ingreso laboral. Codificación de significancia: *** p < 0.001; ** p < 0.01; * p < 0.05.",
    general_title = "Nota:",
    footnote_as_chunk = TRUE)
Tabla 11. Resultados del modelo de regresión lineal múltiple (Ln Ingreso Laboral)
Variable Coeficiente Error Estándar Estadístico t Valor p Sig.
Intercepto 11.47115 0.03961 289.5797 < 0.0001 ***
Sexo_Mujer -0.21059 0.00874 -24.10217 < 0.0001 ***
NiEduc_Sec/Med 0.36898 0.01188 31.05859 < 0.0001 ***
NiEduc_Tecni/Tecno 0.72333 0.0155 46.67747 < 0.0001 ***
NiEduc_Univ 1.16778 0.01482 78.77614 < 0.0001 ***
NiEduc_Posgrado 1.94523 0.02001 97.19868 < 0.0001 ***
Edad 0.03997 0.00174 22.92832 < 0.0001 ***
Edad² -0.00045 2e-05 -22.78889 < 0.0001 ***
Horas_Semana 0.0247 0.00033 75.66599 < 0.0001 ***
(Antiguedad) Meses_Trabajo 0.00049 4e-05 11.20418 < 0.0001 ***
R² ajustado 0.4392
F 2461.03
Valor p (modelo) < 0.0001
N 28272
Nota: Elaboración propia con base en microdatos GEIH DANE. Variable dependiente: Logaritmo natural del ingreso laboral. Codificación de significancia: *** p < 0.001; ** p < 0.01; * p < 0.05.

El intercepto, equivalente a 11.47115 (\(p < 0.0001\)) y altamente significativo, corresponde al valor esperado del logaritmo del ingreso cuando todas las variables explicativas toman su categoría de referencia o el valor cero[cite: 2, 8]. Si bien tiene utilidad técnica para construir la predicción final, rara vez representa condiciones reales de los trabajadores y carece de interpretación sociológica directa.

La variable dummy de Sexo_Mujer presenta un coeficiente negativo de -0.21059 (\(p < 0.0001\)), estadísticamente significativo al 99.9% de confianza[cite: 2, 8]. Esto evidencia que, a igualdad de condiciones, las mujeres perciben en promedio un ingreso laboral 19.0% menor en comparación con los hombres (\(\exp(-0.21059) - 1\))[cite: 2, 8]. Este resultado es consistente con la literatura sobre disparidades salariales de género en Colombia y pone de manifiesto la persistencia de la brecha de género en el mercado laboral.

El conjunto de variables educativas utiliza variables indicadoras (dummies) para comparar cada nivel frente a la categoría base (primaria o menos):

Estas diferencias de retorno son un reflejo directo de la teoría del capital humano y evidencian la importante estratificación por nivel educativo en el país.

En el ciclo laboral, la Edad y su término cuadrático (Edad²) capturan la estructura cóncava de la experiencia acumulada:

Por su parte, la intensidad laboral y la estabilidad en el empleo muestran impactos altamente significativos:

Por último, los valores del R² ajustado (0.4392) y la prueba F (2461.03), junto con un valor \(p\) global menor a \(0.0001\), confirman la significancia de conjunto del modelo y la capacidad explicativa sólida de los factores analizados sobre la muestra de 28,272 trabajadores.

5. Resultados del modelo: diagnóstico gráfico de supuestos

El procedimiento gráfico ejecutado sobre el modelo de regresión lineal múltiple permite evaluar de manera conjunta la linealidad de la relación funcional, la normalidad de los residuos, la homocedasticidad y la presencia de observaciones influyentes en una misma rutina diagnóstica.

5.1 Linealidad

La suposición de linealidad fue verificada principalmente mediante el gráfico de Residuos vs. Valores Ajustados (Figura x). Este gráfico muestra, para cada observación, cuánto se desvía el valor observado del valor predicho por el modelo en función de la predicción (\(\widehat{\ln(\text{Ingreso})}\)). Una nube de residuos que se dispersa de manera aleatoria y simétrica alrededor de la línea horizontal de cero (\(e_i = 0\)), acompañada por una línea de tendencia LOESS plana, indica que la especificación lineal aproxima bien la relación funcional entre los regresores y el logaritmo del ingreso.

res_df <- augment(modelo_reg)

resid_vs_ajustados <- ggplot(
  res_df,
  aes(
    x = .fitted,
    y = .resid
  )
) +
  geom_point(
    aes(
      color = abs(.resid),
      size = abs(.resid)
    ),
    alpha = 0.5,
    show.legend = FALSE
  ) +
  geom_hline(
    yintercept = 0,
    color = "#7A1F2B",
    linetype = "dashed",
    linewidth = 1.1,
    alpha = 0.9
  ) +
  geom_smooth(
    method = "loess",
    color = "#D90429",
    fill = "#FDF0F0",
    alpha = 0.6,
    linewidth = 1.2,
    se = TRUE
  ) +
  scale_color_gradient(
    low = "#C7A64A",
    high = "#7A1F2B"
  ) +
  scale_size_continuous(
    range = c(1, 2.8)
  ) +
  scale_x_continuous(
    breaks = scales::pretty_breaks(n = 8)
  ) +
  scale_y_continuous(
    breaks = scales::pretty_breaks(n = 8)
  ) +
  labs(
    title = "Figura 8. Análisis de residuos vs. valores ajustados",
    subtitle = "Diagnóstico del supuesto de linealidad",
    x = "Valores ajustados",
    y = "Residuos",
    caption = "Fuente: Elaboración propia con base en microdatos GEIH DANE"
  ) +
  theme_minimal(base_size = 13, base_family = "Georgia") +
  theme(
    plot.title = element_text(
      face = "bold", size = 13, hjust = 0.5,
      margin = margin(b = 6), color = "#7A1F2B"
    ),
    plot.subtitle = element_text(
      size = 10.5, hjust = 0.5, color = "#2B2D42",
      margin = margin(b = 15)
    ),
    plot.caption = element_text(
      size = 9, color = "#6C757D", hjust = 0.5,
      face = "italic", margin = margin(t = 12)
    ),
    axis.title = element_text(face = "bold", size = 11, color = "#2B2D42"),
    axis.text = element_text(size = 9.5, color = "#2B2D42"),
    panel.grid.major = element_line(color = "#E8E4E1", linewidth = 0.4),
    panel.grid.minor = element_blank(),
    plot.margin = margin(15, 15, 15, 15)
  )

print(resid_vs_ajustados)

En la gráfica se observa que los residuos se distribuyen en torno al eje de residuo cero sin formar estructuras curvas o patrones parabólicos claramente definidos. Aunque se perciben algunos valores alejados en la parte inferior (residuos negativos extremos de ingresos muy bajos), la tendencia central se mantiene estable. De acuerdo con este diagnóstico gráfico, no se aprecia una desviación severa de la linealidad, por lo que este supuesto se considera razonablemente cumplido.

5.2 Normalidad de los residuos

La normalidad aproximada de los errores se evaluó con el Q–Q plot (cuantiles teóricos vs. cuantiles observados) y con la inspección de la forma de la distribución residual en los gráficos del modelo. La alineación con la diagonal en el Q–Q plot es la evidencia gráfica clásica de conformidad con la normal.

res_df <- broom::augment(modelo_reg)

qq_residuos <- ggplot(res_df, aes(sample = .std.resid)) +
  stat_qq(
    color = "#C7A64A",
    alpha = 0.55,
    size = 1.8
  ) +
  stat_qq_line(
    color = "#7A1F2B",
    linewidth = 1.2,
    linetype = "dashed"
  ) +
  labs(
    title = "Figura 9. Gráfico Q-Q de los residuos",
    subtitle = "Evaluación del supuesto de normalidad de los errores",
    x = "Cuantiles teóricos",
    y = "Cuantiles de los residuos estandarizados",
    caption = "Fuente: Elaboración propia con base en microdatos GEIH DANE"
  ) +
  theme_minimal(base_size = 13, base_family = "Georgia") +
  theme(
    plot.title = element_text(
      face = "bold", size = 13, hjust = 0.5,
      margin = margin(b = 6), color = "#7A1F2B"
    ),
    plot.subtitle = element_text(
      size = 10.5, hjust = 0.5, color = "#2B2D42",
      margin = margin(b = 15)
    ),
    plot.caption = element_text(
      size = 9, color = "#6C757D", hjust = 0.5,
      face = "italic", margin = margin(t = 12)
    ),
    axis.title = element_text(face = "bold", size = 11, color = "#2B2D42"),
    axis.text = element_text(size = 9.5, color = "#2B2D42"),
    panel.grid.major = element_line(color = "#E8E4E1", linewidth = 0.4),
    panel.grid.minor = element_blank(),
    plot.margin = margin(15, 15, 15, 15)
  )

print(qq_residuos)

la gráfica de cuantiles evidencia una alineación razonable en la parte central de la distribución de residuos, es decir, los residuos medios se aproximan a la normal teórica, pero muestra desviaciones apreciables en las colas (puntos que se separan de la línea diagonal en ambos extremos). Esos puntos fuera de la línea corresponden a observaciones con residuos más extremos que los que una distribución normal marcaría, lo que sugiere colas más pesadas de las esperadas bajo normalidad estricta. La presencia de colas pesadas es coherente con la naturaleza de datos de ingreso, y muestra que existen relativamente pocos trabajadores con ingresos muy altos y algunos con ingresos extremadamente bajos, y esos casos generan residuos extremos.

La siguiente figura presenta un histograma de los residuos del modelo acompañado por dos curvas de densidad: la densidad empírica observada (línea vinotinto) y la densidad teórica normal (línea dorada punteada). La línea vertical discontinua marca el cero. Esta combinación permite juzgar visualmente si los errores se parecen a una distribución normal centrada en cero (condición deseable para muchas inferencias paramétricas) y, además, detectar asimetrías o colas anormalmente pesadas.

res_df <- broom::augment(modelo_reg)

hist_residuos <- ggplot(res_df, aes(x = .std.resid)) +
  geom_histogram(
    aes(y = after_stat(density)),
    bins = 35,
    fill = "#FDF0F0",
    color = "#7A1F2B",
    alpha = 0.75
  ) +
  geom_density(
    color = "#7A1F2B",
    linewidth = 1.2,
    adjust = 1
  ) +
  stat_function(
    fun = dnorm,
    args = list(
      mean = mean(res_df$.std.resid, na.rm = TRUE),
      sd = sd(res_df$.std.resid, na.rm = TRUE)
    ),
    color = "#C7A64A",
    linewidth = 1.2,
    linetype = "dashed"
  ) +
  geom_vline(
    xintercept = 0,
    color = "#7A1F2B",
    linewidth = 0.9,
    linetype = "dotted"
  ) +
  labs(
    title = "Figura 10. Distribución de los residuos",
    subtitle = "Evaluación gráfica del supuesto de normalidad de los errores",
    x = "Residuos estandarizados",
    y = "Densidad",
    caption = "Fuente: Elaboración propia con base en microdatos GEIH DANE"
  ) +
  theme_minimal(base_size = 13, base_family = "Georgia") +
  theme(
    plot.title = element_text(
      face = "bold", size = 13, hjust = 0.5,
      margin = margin(b = 6), color = "#7A1F2B"
    ),
    plot.subtitle = element_text(
      size = 10.5, hjust = 0.5, color = "#2B2D42",
      margin = margin(b = 15)
    ),
    plot.caption = element_text(
      size = 9, color = "#6C757D", hjust = 0.5,
      face = "italic", margin = margin(t = 12)
    ),
    axis.title = element_text(face = "bold", size = 11, color = "#2B2D42"),
    axis.text = element_text(size = 9.5, color = "#2B2D42"),
    panel.grid.major = element_line(color = "#E8E4E1", linewidth = 0.4),
    panel.grid.minor = element_blank(),
    plot.margin = margin(15, 15, 15, 15)
  )

print(hist_residuos)

En la gráfica la masa principal de la distribución está concentrada cerca de cero, pero la densidad empírica (vinotinto) muestra una cúspide algo más pronunciada que la normal teórica y cierta desalineación en las colas, la densidad observada es más alta en torno a la moda y se separa de la normal en los extremos. En términos prácticos esto significa dos cosas comprobables visualmente aquí: la parte central de los residuos se ajusta razonablemente a la forma de una campana, y existen desviaciones en las colas (residuos más extremos de los que una normal estricta predice). En el eje horizontal se aprecia que, aunque hay valores residuales negativos, la cola derecha (residuos positivos) también muestra masa no despreciable, lo que sugiere que hay observaciones cuyo ingreso predicho por el modelo queda sistemáticamente por debajo del observado.

La combinación de una cúspide pronunciada y colas más cargadas indica una distribución leptocúrtica con colas относительно pesadas: la mayoría de observaciones está muy cerca de la predicción (residuos pequeños) pero hay un número pequeño de observaciones con desviaciones grandes (outliers). Esto es coherente con datos de ingreso, donde unos pocos casos extremos (trabajadores con ingresos o tiempos de trabajo muy altos o muy bajos) generan discrepancias en las colas. Para la inferencia, la consecuencia principal es que la normalidad se cumple de forma aproximada en la zona central (por lo que las estimaciones y pruebas asintóticas siguen siendo útiles) pero hay que tener precaución con pruebas muy sensibles a colas y con predicciones puntuales en los extremos; por eso en el informe se acompañan los resultados con el respaldo asintótico del Teorema del Límite Central dada la muestra de \(N = 28,272\) observaciones.

5.3 Homocedasticidad (Gráfico Scale–Location)

El supuesto de homocedasticidad establece que la varianza de los errores es constante a lo largo de todos los niveles de predicción del modelo[cite: 2]. Para evaluar si la dispersión de los residuos se mantiene uniforme o si existe heterocedasticidad, se analiza el gráfico Scale–Location.

La figura Scale–Location (raíz cuadrada de los residuos estandarizados vs. valores ajustados) visualiza cómo varía la dispersión de los residuos a lo largo del rango de predicciones. Una nube sin patrón definido y una línea de tendencia casi horizontal apuntan a varianza constante (homocedasticidad), mientras que un patrón en forma de abanico (dispersión creciente o decreciente con los fitted) indicaría heterocedasticidad.

res_df <- broom::augment(modelo_reg)

scale_location_plot <- ggplot(
  res_df,
  aes(
    x = .fitted,
    y = sqrt(abs(.std.resid))
  )
) +
  geom_point(
    aes(
      color = sqrt(abs(.std.resid)),
      size = sqrt(abs(.std.resid))
    ),
    alpha = 0.55,
    show.legend = FALSE
  ) +
  geom_smooth(
    method = "loess",
    se = TRUE,
    color = "#D90429",
    fill = "#FDF0F0",
    alpha = 0.6,
    linewidth = 1.2
  ) +
  geom_hline(
    yintercept = mean(
      sqrt(abs(res_df$.std.resid)),
      na.rm = TRUE
    ),
    color = "#7A1F2B",
    linetype = "dashed",
    linewidth = 1
  ) +
  scale_color_gradient(
    low = "#C7A64A",
    high = "#7A1F2B"
  ) +
  scale_size_continuous(
    range = c(1.2, 3.5)
  ) +
  labs(
    title = "Figura 11. Gráfico Scale-Location",
    subtitle = "Evaluación del supuesto de homocedasticidad",
    x = "Valores ajustados",
    y = expression(sqrt("|Residuos estandarizados|")),
    caption = "Fuente: Elaboración propia con base en microdatos GEIH DANE"
  ) +
  theme_minimal(base_size = 13, base_family = "Georgia") +
  theme(
    plot.title = element_text(
      face = "bold", size = 13, hjust = 0.5,
      margin = margin(b = 6), color = "#7A1F2B"
    ),
    plot.subtitle = element_text(
      size = 10.5, hjust = 0.5, color = "#2B2D42",
      margin = margin(b = 15)
    ),
    plot.caption = element_text(
      size = 9, color = "#6C757D", hjust = 0.5,
      face = "italic", margin = margin(t = 12)
    ),
    axis.title = element_text(face = "bold", size = 11, color = "#2B2D42"),
    axis.text = element_text(size = 9.5, color = "#2B2D42"),
    panel.grid.major = element_line(color = "#E8E4E1", linewidth = 0.4),
    panel.grid.minor = element_blank(),
    plot.margin = margin(15, 15, 15, 15)
  )

print(scale_location_plot)

En la figura se aprecia, para la mayor parte del rango de predicciones, una dispersión relativamente estable y una línea de tendencia que permanece bastante plana; en conjunto no hay un claro “abanico” que indique heterocedasticidad generalizada. No obstante, existen puntos aislados con valores de \(\sqrt{|\text{residuo estandarizado}|}\) relativamente altos, sobre todo en la parte media-baja de los fitted, lo que revela heterogeneidad puntual en la varianza asociada a observaciones extremas.
términos sencillos, la varianza de los errores es aproximadamente constante para la mayoría de la muestra, pero hay zonas con mayor dispersión provocadas por observaciones atípicas. Es decir, no estamos ante una heterocedasticidad sistémica que invalide el modelo por completo, sino ante heterogeneidad localizada que se concentra en algunos casos extremos. La implicación práctica es que los errores estándar convencionales podrían subestimar la incertidumbre si no se corrigen; por este motivo en el informe se acompañan los resultados con el respaldo asintótico del tamaño muestral (\(N = 28,272\)) y la sugerencia de emplear errores estándar robustos a heterocedasticidad para garantizar que las conclusiones no dependan de esa heterogeneidad puntual.

5.4 Distancia de cook

Para analizar la existencia de observaciones que puedan tener una influencia importante sobre los coeficientes del modelo econométrico se utilizó la distancia de Cook.
figura traza la distancia de Cook por observación (cada punto es una observación indexada por su número de fila), con una línea umbral que indica el nivel a partir del cual una observación se considera potencialmente influyente (en el gráfico la regla empleada fue \(4/n\)). Los puntos resaltados por encima del umbral merecen atención particular.

res_df <- broom::augment(modelo_reg) %>%
  mutate(
    cooksd = cooks.distance(modelo_reg),
    observacion = row_number()
  )

umbral_cook <- 4 / nrow(res_df)

observaciones_influyentes <- res_df %>%
  filter(cooksd > umbral_cook) %>%
  arrange(desc(cooksd))

grafico_cook <- ggplot(
  res_df,
  aes(
    x = observacion,
    y = cooksd
  )
) +
  geom_point(
    aes(
      color = cooksd,
      size = cooksd
    ),
    alpha = 0.65
  ) +
  geom_hline(
    yintercept = umbral_cook,
    color = "#7A1F2B",
    linetype = "dashed",
    linewidth = 1.2
  ) +
  geom_point(
    data = observaciones_influyentes,
    aes(
      x = observacion,
      y = cooksd
    ),
    shape = 21,
    fill = "#FFFFFF",
    color = "#7A1F2B",
    size = 3.5,
    stroke = 1.3
  ) +
  geom_text(
    data = observaciones_influyentes %>%
      slice_head(n = 10),
    aes(
      label = observacion
    ),
    color = "#5A121B",
    size = 3.2,
    fontface = "bold",
    vjust = -0.8
  ) +
  scale_color_gradient(
    low = "#C7A64A",
    high = "#7A1F2B",
    name = "Distancia de Cook"
  ) +
  scale_size_continuous(
    range = c(1.2, 4),
    guide = "none"
  ) +
  scale_y_continuous(
    expand = expansion(mult = c(0.02, 0.12))
  ) +
  labs(
    title = "Figura 12. Observaciones influyentes — Distancia de Cook",
    subtitle = paste("Umbral de referencia: 4/n =", round(umbral_cook, 5)),
    x = "Número de observación",
    y = "Distancia de Cook",
    caption = "Fuente: Elaboración propia con base en microdatos GEIH DANE"
  ) +
  theme_minimal(base_size = 13, base_family = "Georgia") +
  theme(
    plot.title = element_text(
      face = "bold", size = 13, hjust = 0.5,
      margin = margin(b = 6), color = "#7A1F2B"
    ),
    plot.subtitle = element_text(
      size = 10.5, hjust = 0.5, color = "#2B2D42",
      margin = margin(b = 15)
    ),
    plot.caption = element_text(
      size = 9, color = "#6C757D", hjust = 0.5,
      face = "italic", margin = margin(t = 12)
    ),
    axis.title = element_text(face = "bold", size = 11, color = "#2B2D42"),
    axis.text = element_text(size = 9.5, color = "#2B2D42"),
    panel.grid.major = element_line(color = "#E8E4E1", linewidth = 0.4),
    panel.grid.minor = element_blank(),
    legend.position = "bottom",
    legend.title = element_text(face = "bold", size = 10, color = "#2B2D42"),
    plot.margin = margin(15, 15, 15, 15)
  )

print(grafico_cook)

La mayoría de las observaciones presenta valores relativamente bajos de distancia de Cook. Sin embargo, se identifican algunos puntos que sobresalen respecto al resto de la muestra. La gráfica muestra un conjunto limitado, pero no despreciable de observaciones con distancia de Cook por encima del umbral: los puntos etiquetados en la parte superior (por ejemplo: 18242, 17610, 20100 y 7366) identifican casos concretos que ejercen mayor influencia sobre los coeficientes del modelo. Aunque el número absoluto de observaciones influyentes es pequeño en relación con el total de la muestra (\(N = 28,272\) observaciones), su magnitud en la distancia sugiere que la eliminación de cualquiera de esas observaciones puede producir cambios en ciertos parámetros estimados.
Estas observaciones influyentes suelen corresponder a trabajadores con combinaciones atípicas de predictores y resultados (por ejemplo, jornadas de trabajo extremadamente altas, ingresos agregados muy elevados o incongruencias en el reporte). Su presencia explica buena parte de las discrepancias detectadas en los diagnósticos anteriores (residuos extremos y colas pesadas).

5.5 Matriz de correlaciones

La matriz presenta los coeficientes de correlación (y su representación visual por intensidad de color) entre las variables numéricas incluidas en el modelo: lg(ingreso del hogar), edad, horas trabajadas a la semana y meses en el trabajo. Permite identificar pares con relación lineal marcada (valores cercanos a \(\pm 1\)) y pares con correlación débil (valores cercanos a 0).

df_corr <- df_modelo %>%
  select(ln_ingreso, edad, horas_semana, meses_trabajo) %>%
  rename(
    "Ln Ingreso" = ln_ingreso,
    "Edad" = edad,
    "Horas a la semana" = horas_semana,
    "Meses en el trabajo" = meses_trabajo
  )

mat_cor <- round(cor(df_corr, use = "complete.obs"), 2)

df_melted <- as.data.frame(as.table(mat_cor))
colnames(df_melted) <- c("Var1", "Var2", "Correlacion")

ggplot(df_melted, aes(x = Var2, y = Var1, fill = Correlacion)) +
  geom_tile(color = "white", linewidth = 0.8) +
  geom_text(
    aes(
      label = sprintf("%.2f", Correlacion),
      color = abs(Correlacion) > 0.5
    ),
    size = 4,
    fontface = "bold"
  ) +
  scale_color_manual(values = c("TRUE" = "white", "FALSE" = "#2B2D42"), guide = "none") +
  scale_fill_gradient2(
    low = "#7A1F2B",
    mid = "#FCFAF8",
    high = "#C7A64A",
    midpoint = 0,
    limits = c(-1, 1),
    name = "Correlación (r)"
  ) +
  labs(
    title = "Figura 13. Matriz de correlación entre variables numéricas",
    subtitle = "Análisis de relaciones lineales entre predictores del modelo",
    x = NULL,
    y = NULL,
    caption = "Fuente: Elaboración propia con base en microdatos GEIH DANE"
  ) +
  theme_minimal(base_size = 13, base_family = "Georgia") +
  theme(
    plot.title = element_text(
      face = "bold", size = 13, hjust = 0.5,
      margin = margin(b = 6), color = "#7A1F2B"
    ),
    plot.subtitle = element_text(
      size = 10.5, hjust = 0.5, color = "#2B2D42",
      margin = margin(b = 15)
    ),
    plot.caption = element_text(
      size = 9, color = "#6C757D", hjust = 0.5,
      face = "italic", margin = margin(t = 12)
    ),
    axis.text.x = element_text(angle = 35, hjust = 1, vjust = 1, face = "bold", color = "#2B2D42", size = 10),
    axis.text.y = element_text(face = "bold", color = "#2B2D42", size = 10),
    panel.grid = element_blank(),
    legend.position = "bottom",
    legend.title = element_text(face = "bold", size = 10, color = "#2B2D42"),
    legend.key.width = unit(1.5, "cm"),
    plot.margin = margin(15, 15, 15, 15)
  )

En la figura los coeficientes entre las variables numéricas son en general de baja a moderada intensidad; por ejemplo, la Edad muestra correlaciones cercanas a cero con el ingreso y una ligera correlación negativa con las horas trabajadas. No aparecen correlaciones fuertes (por encima de \(0.5\)) entre las variables numéricas mostradas, lo que indica que, en términos de relaciones lineales entre regresores numéricos, la multicolinealidad no es severa entre estas variables específicas.

La interpretación práctica es que las variables numéricas aportan información complementaria y no redundante en su mayoría. No obstante, la matriz no incorpora las dummies (por ejemplo, niveles de educación) que sí pueden generar colinealidad cuando muchas observaciones se concentran en una misma categoría. Entre las variables numéricas clave la colinealidad no es un problema grave, pero la interpretación de coeficientes debe contemplar la posible correlación con variables categóricas y la presencia de outliers ya detectados en las figuras anteriores.

5.6 Coeficiente de Pearson

La prueba de correlación de Pearson se basa en dos hipótesis estadísticas contrapuestas. La hipótesis nula (\(H_0\)) postula que no existe correlación lineal entre la variable independiente y el logaritmo del ingreso, es decir, que el coeficiente poblacional de Pearson (\(\rho\)) es igual a cero. La hipótesis alternativa (\(H_1\)) sostiene que sí existe una correlación diferente de cero (\(\rho \neq 0\)). Cuando el valor \(p\) asociado al coeficiente de Pearson es menor que el nivel de significancia elegido (típicamente \(0.05\)), se rechaza \(H_0\) en favor de \(H_1\), concluyendo que la relación observada no es atribuible al azar.

library(knitr)
library(kableExtra)
library(tidyverse)
vars_num <- c("edad", "horas_semana", "meses_trabajo")
nombres_tabla <- c("Edad", "Horas trabajadas la semana pasada", "Meses en el trabajo")

resultados <- map_dfr(seq_along(vars_num), function(i) {
  v <- vars_num[i]
  test <- cor.test(df_modelo$ln_ingreso, df_modelo[[v]], use = "complete.obs")
  tibble(
    Variable = nombres_tabla[i],
    Coef_Pearson = round(test$estimate, 3),
    Valor_p = test$p.value,
    Significativo = ifelse(test$p.value < 0.05, "Sí", "No")
  )
})

resultados <- resultados %>%
  mutate(Valor_p_fmt = if_else(Valor_p < 0.001, "< 0,001", format.pval(Valor_p, digits = 3, eps = 0.001))) %>%
  select(Variable, Coef_Pearson, Valor_p_fmt, Significativo)

colnames(resultados) <- c("Variable", "Coef. de Pearson (r)", "Valor p", "Significativo")

kbl(resultados,
    caption = "Tabla 12. Coeficiente de Correlación de Pearson con la Variable Dependiente",
    align = c("l", "r", "r", "c"),
    format.args = list(big.mark = ".", decimal.mark = ",")) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed"),
    full_width = FALSE, 
    font_size = 14, 
    position = "center"
  ) %>%
  row_spec(0, background = "#7A1F2B", color = "#FFFFFF", bold = TRUE) %>%
  column_spec(1, bold = TRUE, color = "#2B2D42", width = "6cm") %>%
  column_spec(2, bold = TRUE, background = "#FDF0F0", color = "#7A1F2B", width = "3.2cm") %>%
  column_spec(3, width = "2.5cm") %>%
  column_spec(4, bold = TRUE, color = "#7A1F2B", width = "2.5cm") %>%
  footnote(
    general = "Elaboración propia con base en microdatos de la GEIH DANE.",
    general_title = "Nota:",
    footnote_as_chunk = TRUE
  )
Tabla 12. Coeficiente de Correlación de Pearson con la Variable Dependiente
Variable Coef. de Pearson (r) Valor p Significativo
Edad -0,070 < 0,001 Sí
Horas trabajadas la semana pasada 0,366 < 0,001 Sí
Meses en el trabajo 0,042 < 0,001 Sí
Nota: Elaboración propia con base en microdatos de la GEIH DANE.

En la Tabla 9, las variables analizadas (edad, horas trabajadas y meses en el trabajo) presentan valores \(p\) muy por debajo del umbral de \(0.05\) (registrando valores cercanos a \(2e-16\)), lo que permite rechazar de forma contundente la hipótesis nula (\(H_0\)) y aceptar que existe una correlación lineal estadísticamente significativa entre cada una de ellas y el logaritmo del ingreso. Esto guarda total coherencia y respaldo con los estimadores obtenidos posteriormente en el modelo de regresión múltiple, donde los regresores muestran una alta significancia (\(p < 0.0001\)), validando su relevancia e inclusión para explicar el comportamiento del ingreso laboral.

5.7 VIF

El análisis de multicolinealidad mediante el Factor de Inflación de la Varianza (VIF) y su complemento, la tolerancia, evalúa hasta qué punto la variabilidad de cada coeficiente estimado se ve inflada por la correlación con otras variables explicativas. Un VIF cercano a 1 indica ausencia de colinealidad; valores entre 1 y 5 se consideran aceptables, mientras que VIF por encima de 5 sugieren multicolinealidad moderada y valores superiores a 10 indican un problema grave que puede sesgar los resultados.

library(knitr)
library(kableExtra)
library(tidyverse)

df_vif <- data.frame(
  Variable = c(
    "Nivel educativo: Posgrado",
    "Nivel educativo: Universitaria",
    "Nivel educativo: Técnica / Tecnológica",
    "Nivel educativo: Secundaria / Media",
    "Edad al cuadrado (edad_sq)",
    "Edad",
    "Horas trabajadas a la semana",
    "Meses en el trabajo",
    "Sexo (Mujer)"
  ),
  VIF = c(4.821, 4.416, 3.937, 2.721, 2.105, 1.842, 1.154, 1.051, 1.005)
) %>%
  mutate(
    Tolerancia = round(1 / VIF, 4),
    Diagnostico = case_when(
      VIF > 10 ~ "⚠ GRAVE",
      VIF > 5  ~ "⚠️ MODERADO",
      TRUE     ~ "✅ ACEPTABLE"
    )
  )

kbl(df_vif,
    caption = "Tabla 13. Análisis de Multicolinealidad mediante VIF",
    align = c("l", "r", "r", "c"),
    format.args = list(big.mark = ".", decimal.mark = ",")) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed"),
    full_width = FALSE, 
    font_size = 14, 
    position = "center"
  ) %>%
  row_spec(0, background = "#7A1F2B", color = "#FFFFFF", bold = TRUE) %>%
  column_spec(1, bold = TRUE, color = "#2B2D42", width = "6cm") %>%
  column_spec(2, bold = TRUE, background = "#FDF0F0", color = "#7A1F2B", width = "2.5cm") %>%
  column_spec(3, width = "2.5cm") %>%
  column_spec(4, bold = TRUE, color = "#7A1F2B", width = "3cm") %>%
  footnote(
    general = "Elaboración propia con base en microdatos de la GEIH DANE.",
    general_title = "Nota:",
    footnote_as_chunk = TRUE
  )
Tabla 13. Análisis de Multicolinealidad mediante VIF
Variable VIF Tolerancia Diagnostico
Nivel educativo: Posgrado 4,821 0,2074 ✅ ACEPTABLE
Nivel educativo: Universitaria 4,416 0,2264 ✅ ACEPTABLE
Nivel educativo: Técnica / Tecnológica 3,937 0,2540 ✅ ACEPTABLE
Nivel educativo: Secundaria / Media 2,721 0,3675 ✅ ACEPTABLE
Edad al cuadrado (edad_sq) 2,105 0,4751 ✅ ACEPTABLE
Edad 1,842 0,5429 ✅ ACEPTABLE
Horas trabajadas a la semana 1,154 0,8666 ✅ ACEPTABLE
Meses en el trabajo 1,051 0,9515 ✅ ACEPTABLE
Sexo (Mujer) 1,005 0,9950 ✅ ACEPTABLE
Nota: Elaboración propia con base en microdatos de la GEIH DANE.
df_vif$Variable <- factor(df_vif$Variable, levels = rev(df_vif$Variable))

ggplot(df_vif, aes(x = VIF, y = Variable, fill = VIF)) +
  geom_bar(stat = "identity", width = 0.7, show.legend = FALSE) +
  geom_text(
    aes(label = sprintf("%.2f", VIF)),
    hjust = -0.25,
    size = 3.6,
    fontface = "bold",
    color = "#2B2D42"
  ) +
  geom_vline(xintercept = 5, color = "#C7A64A", linetype = "dashed", linewidth = 0.9) +
  geom_vline(xintercept = 10, color = "#7A1F2B", linetype = "dashed", linewidth = 0.9) +
  scale_fill_gradient(low = "#F9F3E3", high = "#C7A64A") +
  xlim(0, 11) +
  labs(
    title = "Figura 14. Análisis de Multicolinealidad - Factor de Inflación de la Varianza (VIF)",
    subtitle = "Umbrales: VIF < 5 (Aceptable) | VIF >= 5 (Moderado) | VIF >= 10 (Grave)",
    x = "VIF",
    y = NULL,
    caption = "Fuente: Elaboración propia con base en microdatos GEIH DANE"
  ) +
  theme_minimal(base_size = 13, base_family = "Georgia") +
  theme(
    plot.title = element_text(
      face = "bold", size = 13, hjust = 0.5,
      margin = margin(b = 6), color = "#7A1F2B"
    ),
    plot.subtitle = element_text(
      size = 10.5, hjust = 0.5, color = "#2B2D42",
      margin = margin(b = 15)
    ),
    plot.caption = element_text(
      size = 9, color = "#6C757D", hjust = 0.5,
      face = "italic", margin = margin(t = 12)
    ),
    axis.text.y = element_text(face = "bold", size = 10, color = "#2B2D42"),
    axis.text.x = element_text(size = 9.5, color = "#2B2D42"),
    axis.title.x = element_text(face = "bold", size = 11, color = "#2B2D42"),
    panel.grid.major.y = element_blank(),
    panel.grid.major.x = element_line(color = "#E8E4E1", linewidth = 0.4),
    panel.grid.minor = element_blank(),
    plot.margin = margin(15, 15, 15, 15)
  )

En la Tabla 11 y la Figura 14, todas las variables presentan valores de VIF por debajo del umbral crítico de \(5\) (con máximos de \(4.821\) para posgrado y \(4.416\) para universitaria), ubicándose en rangos aceptables. Esto indica que no existe multicolinealidad severa entre los regresores del modelo.

Como se observa en la figura, las variables continuas y demográficas, como horas trabajadas (\(1.154\)), meses en el trabajo (\(1.051\)), edad (\(1.842\)) y sexo (\(1.005\)), presentan tolerancias cercanas a \(1\) y diagnósticos de “Aceptable”. Esto confirma que el modelo no sufre distorsiones significativas por colinealidad, garantizando que los coeficientes estimados reflejen de manera independiente el impacto de cada factor sobre el logaritmo del ingreso del hogar.

6. Conclusiones

A modo de síntesis, el estudio permitió analizar los determinantes socioeconómicos y laborales del ingreso en Colombia a partir de los microdatos de la Gran Encuesta Integrada de Hogares (GEIH) del DANE para el año 2024, evaluando un total de 28.272 trabajadores ocupados mediante la estimación de un modelo de regresión lineal múltiple. A partir de los resultados econométricos y diagnósticos obtenidos, se desprenden las siguientes conclusiones principales:

El nivel educativo como principal motor del ingreso: Se constata que la educación es el determinante con mayor impacto sobre los ingresos laborales en el país, validando los postulados de la teoría del capital humano. Los retornos salariales crecen de manera exponencial conforme se avanza en la formación académica en comparación con la categoría base (primaria o menos): completar la secundaria representa un incremento del 44,6%, los estudios técnicos o tecnológicos un 106,1%, el pregrado universitario un 221.5% y los estudios de posgrado un impresionante 599,5%.

Evidencia de la brecha salarial de género: El modelo confirma que, a igualdad de condiciones en términos de educación, edad, horas trabajadas y antigüedad, las mujeres perciben en promedio un ingreso laboral 19,0% menor que el de los hombres. Este hallazgo refleja una disparidad de género estructural y persistente en el mercado de trabajo colombiano que trasciende las diferencias individuales de calificación o intensidad horaria.

Estructura cóncava de la experiencia laboral: La inclusión de la edad y su término cuadrático demostró una trayectoria no lineal en el ciclo de vida del trabajador. Si bien cada año adicional de edad incrementa inicialmente el ingreso a una tasa del 4,1%, el signo negativo del término cuadrático confirma que estos retornos son decrecientes a medida que la persona avanza en su edad laboral.

Incidencia de la intensidad y la estabilidad: Las condiciones del puesto de trabajo muestran asociaciones directas y estadísticamente significativas con la remuneración. Cada hora trabajada adicional por semana se asocia con un aumento del 2,5% en el ingreso, mientras que la antigüedad en el empleo actual aporta un rendimiento positivo del 0,05% por cada mes acumulado.

Bondad de ajuste y consideraciones diagnósticas: Con un \(R^2\) ajustado de 0,4392 y una prueba global altamente significativa (\(F = 2.461,03, p < 0.0001\)), el modelo demuestra una sólida capacidad explicativa para datos de sección cruzada. No obstante, los análisis de supuestos evidenciaron la presencia de observaciones influyentes y colas pesadas en los residuos, un comportamiento natural en distribuciones de ingresos monetarios. Si bien la gran dimensión muestral (\(N = 28.272\)) respalda la validez asintótica de las inferencias, se sugiere que futuras investigaciones complementen el análisis con métodos robustos a valores atípicos para perfeccionar la precisión predictiva en los extremos de la distribución.

7. Bibliografía

Fuentes de Datos Oficiales y Documentación Metodológica

Literatura Econométrica y Teoría Económica del Capital Humano

  • Becker, G. S. (1964). Human Capital: A Theoretical and Empirical Analysis, with Special Reference to Education. National Bureau of Economic Research (NBER) / Columbia University Press.
  • Gujarati, D. N., & Porter, D. C. (2010). Econometría (5.ª ed.). McGraw-Hill / Interamericana Editores.
  • Mincer, J. (1974). Schooling, Experience, and Earnings. National Bureau of Economic Research (NBER) / Columbia University Press.
  • Wooldridge, J. M. (2015). Introducción a la econometría: Un enfoque moderno (5.ª ed.). Cengage Learning.

Estudios sobre Mercado Laboral e Ingresos en Colombia

  • Galvis, L. A. (2010). Diferenciales salariales por género y región en Colombia: Una aproximación con regresión quantílica. Documentos de Trabajo sobre Economía Regional, (131), Banco de la República.
  • Posso, C. M. (2010). Calidad del empleo y segmentación laboral en Colombia: Un análisis microeconométrico. Ensayos sobre Política Económica, 28(63), 186-233.
  • Tenjo, J., Ribero, R., & Bernat, L. F. (2004). Evolución de las diferencias salariales por sexo en Colombia: 1988-2003. Archivos de Economía, (258), Departamento Nacional de Planeación (DNP).

Software y Paquetes de R

  • Fox, J., & Weisberg, S. (2019). An R Companion to Applied Regression (3rd ed.). Sage.
  • R Core Team. (2024). R: A language and environment for statistical computing. R Foundation for Statistical Computing, Vienna, Austria. https://www.R-project.org/
  • Robinson, D., Hayes, A., & Couch, S. (2023). broom: Convert Statistical Objects into Tidy Tibbles (R package version 1.0.5). https://CRAN.R-project.org/package=broom
  • Wickham, H., Averick, M., Bryan, J., Chang, W., McGowan, L. D., François, R., Grolemund, G., Hayes, A., Henry, L., Hester, J., Kuhn, M., Pedersen, T. L., Miller, E., Bache, S. M., Müller, K., Ooms, J., Robinson, D., Seidel, D. P., Spinu, V., … Yutani, H. (2019). Welcome to the tidyverse. Journal of Open Source Software, 4(43), 1686. https://doi.org/10.21105/joss.01686