Cargamos los paquetes necesarios para el análisis (tidyverse y readxl), así como la base de datos del examen. También se revisa de forma general la estructura de la base para identificar las variables disponibles.

# Paquetes
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   4.0.0     ✔ tibble    3.2.1
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(readxl)

# Importar la base 
datos = read_xlsx(file.choose())

# Checar estructura general
glimpse(datos)
## Rows: 194,510
## Columns: 11
## $ folioviv    <dbl> 100013605, 100013605, 100013606, 100013606, 100017801, 100…
## $ foliohog    <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
## $ numren      <dbl> 1, 2, 1, 3, 1, 2, 1, 1, 1, 1, 3, 1, 2, 1, 2, 1, 3, 1, 2, 4…
## $ FVH_numrem  <chr> "10001360511", "10001360512", "10001360611", "10001360613"…
## $ Entidad_cod <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
## $ Entidad     <chr> "Aguascalientes", "Aguascalientes", "Aguascalientes", "Agu…
## $ Zona        <chr> "Centro", "Centro", "Centro", "Centro", "Centro", "Centro"…
## $ parentesco  <dbl> 101, 301, 101, 301, 101, 201, 101, 101, 101, 101, 301, 101…
## $ sexo_cod    <chr> "Mujer", "Mujer", "Hombre", "Hombre", "Hombre", "Mujer", "…
## $ edad        <dbl> 48, 17, 46, 17, 26, 26, 29, 63, 33, 60, 30, 76, 73, 74, 68…
## $ ingreso     <dbl> 6295.08, 5409.83, 21639.34, 1573.77, 23606.55, 983.60, 678…
head(datos)
## # A tibble: 6 × 11
##    folioviv foliohog numren FVH_numrem  Entidad_cod Entidad     Zona  parentesco
##       <dbl>    <dbl>  <dbl> <chr>             <dbl> <chr>       <chr>      <dbl>
## 1 100013605        1      1 10001360511           1 Aguascalie… Cent…        101
## 2 100013605        1      2 10001360512           1 Aguascalie… Cent…        301
## 3 100013606        1      1 10001360611           1 Aguascalie… Cent…        101
## 4 100013606        1      3 10001360613           1 Aguascalie… Cent…        301
## 5 100017801        1      1 10001780111           1 Aguascalie… Cent…        101
## 6 100017801        1      2 10001780112           1 Aguascalie… Cent…        201
## # ℹ 3 more variables: sexo_cod <chr>, edad <dbl>, ingreso <dbl>

Análisis descriptivo inicial

A continuación se realiza un análisis descriptivo de la variable de interés ingreso (ingreso trimestral). Se calculan medidas de tendencia central, dispersión y posición, lo cual permite tener un primer acercamiento a la distribución de esta variable.

# Análisis descriptivo básico de ingreso trimestral
summary(datos$ingreso)
##     Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
##        0     2374     8609    13785    17902 10688918
mean(datos$ingreso, na.rm = TRUE)
## [1] 13784.77
median(datos$ingreso, na.rm = TRUE)
## [1] 8608.69
sd(datos$ingreso, na.rm = TRUE)
## [1] 35524.93
var(datos$ingreso, na.rm = TRUE)
## [1] 1262020629
quantile(datos$ingreso, probs = c(0.25, 0.5, 0.75), na.rm = TRUE)
##      25%      50%      75% 
##  2373.62  8608.69 17901.63
IQR(datos$ingreso, na.rm = TRUE)
## [1] 15528.01

Realizamos visualizaciones básicas de la distribución del ingreso trimestral, utilizando un histograma. un diagrama de caja y un gráfico de violin. Estas gráficas ayudan a identificar asimetrías, concentración de observaciones y posibles valores extremos.

# Histograma general del ingreso trimestral 
ggplot(datos, aes(x = ingreso)) +
  geom_histogram(fill = "plum") +
  scale_x_continuous(labels = scales::comma) +
  labs(
    title = "Distribución del ingreso trimestral",
    x = "Ingreso trimestral",
    y = "Frecuencia"
  ) +
  theme_classic()
## `stat_bin()` using `bins = 30`. Pick better value `binwidth`.

# Boxplot del ingreso 
ggplot(datos, aes(y = ingreso)) +
  geom_boxplot(fill = "plum", alpha = 0.8, outlier.alpha = 0.4) +
  scale_y_continuous(labels = scales::comma) +
  labs(
    title = "Caja y bigotes del ingreso trimestral (muestra completa)",
    y = "Ingreso trimestral"
  ) +
  theme_classic()

# Gráfico de violín del ingreso trimestral 
ggplot(datos, aes(x = "", y = ingreso)) +
  geom_violin(fill = "plum", alpha = 0.6, trim = TRUE) +
  scale_y_continuous(labels = scales::comma) +
  labs(
    title = "Distribución del ingreso trimestral (violín, muestra completa)",
    x = "",
    y = "Ingreso trimestral"
  ) +
  theme_classic()

Los resultados descriptivos muestran que el ingreso trimestral está fuertemente sesgado a la derecha: el mínimo es 0, el primer cuartil ronda los $2,374, la mediana unos $8,609 y el tercer cuartil cerca de $17,902, mientras que el máximo llega a más de 10 millones. El promedio ($13,785) es bastante mayor que la mediana, lo que indica que unos pocos hogares con ingresos muy altos empujan hacia arriba la media. La desviación estándar (~$35,525) y el IQR (~$15,528) reflejan una dispersión importante, pero visualmente, en el histograma, el boxplot y el gráfico de violín casi toda la masa de observaciones queda concentrada cerca de cero y se observa una cola muy larga de valores extremos, lo que explica por qué los gráficos parecen “aplastados”

Filtrado de la base de datos

Calculamos el primer cuartil (1st Qu.) de la variable ingreso y se construye una nueva base filtrada que conserva únicamente las observaciones con ingreso mayor al primer cuartil y menor o igual a 30,000. Este filtro permite concentrar el análisis en un rango intermedio de ingresos, excluyendo tanto los valores más bajos como los extremadamente altos.

# Primer cuartil del ingreso
q1_ingreso = quantile(datos$ingreso, probs = 0.25, na.rm = TRUE)
q1_ingreso
##     25% 
## 2373.62
# Filtro: ingreso > 1er cuartil y hasta 30,000
datos_filtrados = datos %>% 
  filter(ingreso > q1_ingreso, ingreso <= 30000)

# Revisar cómo quedó
summary(datos_filtrados$ingreso)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    2375    5870   11739   12480   17705   30000
nrow(datos_filtrados)
## [1] 126760

A continuación se presenta el histograma del ingreso trimestral para la base filtrada (ingreso mayor al primer cuartil y menor o igual a 30,000). Se incluyen líneas de referencia para la media y la mediana, y se formatea el eje horizontal para facilitar la lectura de los montos.

# Cálculo de media y mediana en la base filtrada
media_filtrada   <- mean(datos_filtrados$ingreso, na.rm = TRUE)
mediana_filtrada <- median(datos_filtrados$ingreso, na.rm = TRUE)

# Histograma estético del ingreso en la base filtrada
ggplot(datos_filtrados, aes(x = ingreso)) +
  geom_histogram(
    bins  = 40,
    fill  = "plum",
    color = "white",
    alpha = 0.8
  ) +
  geom_vline(aes(xintercept = media_filtrada),
             linetype = "dashed", linewidth = 0.7) +
  geom_vline(aes(xintercept = mediana_filtrada),
             linetype = "dotted", linewidth = 0.7) +
  scale_x_continuous(
    labels = scales::comma,
    breaks = seq(0, 30000, by = 5000)
  ) +
  labs(
    title = "Distribución del ingreso (entre 1er cuartil y 30,000)",
    subtitle = "Líneas punteada: mediana | Línea discontinua: media",
    x = "Ingreso trimestral",
    y = "Frecuencia"
  ) +
  theme_classic()

A continuación se presenta un resumen del ingreso trimestral en la base filtrada, que complementa la información del histograma y permite describir el nivel y la dispersión dentro del rango considerado (> 1er cuartil y ≤ 30,000).

# Resumen del ingreso en la base filtrada
resumen_filtrado <- datos_filtrados %>% 
  summarise(
    n              = n(),
    min_ingreso    = min(ingreso, na.rm = TRUE),
    q1_ingreso     = quantile(ingreso, 0.25, na.rm = TRUE),
    mediana        = median(ingreso, na.rm = TRUE),
    media          = mean(ingreso, na.rm = TRUE),
    q3_ingreso     = quantile(ingreso, 0.75, na.rm = TRUE),
    max_ingreso    = max(ingreso, na.rm = TRUE),
    sd_ingreso     = sd(ingreso, na.rm = TRUE),
    iqr_ingreso    = IQR(ingreso, na.rm = TRUE)
  )

resumen_filtrado
## # A tibble: 1 × 9
##        n min_ingreso q1_ingreso mediana  media q3_ingreso max_ingreso sd_ingreso
##    <int>       <dbl>      <dbl>   <dbl>  <dbl>      <dbl>       <dbl>      <dbl>
## 1 126760       2375.      5870.  11739. 12480.     17705.      30000.      7549.
## # ℹ 1 more variable: iqr_ingreso <dbl>

En la muestra filtrada (126 760 observaciones con ingresos mayores al primer cuartil y menores o iguales a 30 000 pesos trimestrales) el ingreso típico se sitúa alrededor de 11 739 pesos (mediana), mientras que la media, ligeramente superior, es de 12 480 pesos, lo que indica una distribución aún sesgada hacia la derecha pero mucho menos extrema que en la base completa.

La mayor parte de los hogares se concentra entre el primer cuartil, cercano a 5 870 pesos, y el tercer cuartil, alrededor de 17 705 pesos, con un rango intercuartílico de aproximadamente 11 835 pesos y una desviación estándar cercana a 7 549 pesos, reflejando una dispersión importante dentro de este segmento “medio” de la distribución.

El histograma del ingreso filtrado confirma esta idea: se observa una concentración relevante de hogares con ingresos entre aproximadamente 3 000 y 18 000 pesos trimestrales, mientras que los montos próximos al máximo del rango considerado son relativamente poco frecuentes. La línea de la media aparece ligeramente desplazada a la derecha de la mediana, coherente con el sesgo hacia ingresos más altos, y se aprecian picos en ciertos tramos del eje horizontal, lo que sugiere que muchos hogares reportan montos redondeados y genera acumulaciones en niveles específicos dentro de este rango intermedio.

En conjunto, el recorte aplicado al ingreso reduce la influencia de los valores extremadamente bajos y muy altos presentes en la base completa y permite describir con mayor claridad el comportamiento del ingreso trimestral de los hogares ubicados en la zona central de la distribución.

Análisis del ingreso por sexo

Primero seleccionamos las variables relevantes y se calcula un resumen del ingreso trimestral por sexo, utilizando la base filtrada. Esto permite comparar el nivel y la dispersión del ingreso entre hombres y mujeres dentro del rango (> 1er cuartil y ≤ 30,000).

# Selección de variables relevantes sobre la base filtrada
base_filtrada_sel <- datos_filtrados %>% 
  select(Entidad, Zona, sexo_cod, edad, ingreso)

# Resumen del ingreso por sexo
ingreso_por_sexo <- base_filtrada_sel %>% 
  group_by(sexo_cod) %>% 
  summarise(
    n              = n(),
    ingreso_medio  = mean(ingreso, na.rm = TRUE),
    mediana        = median(ingreso, na.rm = TRUE),
    sd_ingreso     = sd(ingreso, na.rm = TRUE),
    q1             = quantile(ingreso, 0.25, na.rm = TRUE),
    q3             = quantile(ingreso, 0.75, na.rm = TRUE)
  )

ingreso_por_sexo
## # A tibble: 2 × 7
##   sexo_cod     n ingreso_medio mediana sd_ingreso    q1     q3
##   <chr>    <int>         <dbl>   <dbl>      <dbl> <dbl>  <dbl>
## 1 Hombre   72487        13587.  12984.      7566. 7043. 19076.
## 2 Mujer    54273        11002.   9000.      7268. 4891. 15429.

A continuación se presenta un diagrama de caja del ingreso trimestral por sexo, basado en la base filtrada. Este gráfico permite visualizar diferencias en la mediana, el rango intercuartílico y la presencia de valores altos dentro del rango considerado.

ggplot(base_filtrada_sel, aes(x = as.factor(sexo_cod), y = ingreso, fill = as.factor(sexo_cod))) +
  geom_boxplot(alpha = 0.7, outlier.alpha = 0.3) +
  scale_y_continuous(labels = scales::comma) +
  labs(
    title = "Ingreso trimestral por sexo\n(> 1er cuartil y ≤ 30,000)",
    x = "Sexo (código)",
    y = "Ingreso trimestral",
    fill = "Sexo"
  ) +
  theme_classic()

En la muestra filtrada se observa una brecha clara de ingreso entre hombres y mujeres. Los hombres tienen un ingreso promedio de 13,587 pesos y una mediana de 12,984 pesos, mientras que en las mujeres el ingreso promedio es de 11,002 pesos y la mediana de 9,000 pesos aproximadamente. Esto implica que, incluso dentro del tramo intermedio de la distribución (entre el primer cuartil y 30,000 pesos), los hombres concentran ingresos típicamente más altos.

Además, el rango intercuartílico es más amplio en hombres (de unos 7,043 a 19,076 pesos) que en mujeres (de aproximadamente 4,891 a 15,429 pesos), lo que sugiere una mayor dispersión entre ellos: hay más hombres tanto en la parte media como cerca del límite superior del rango analizado, mientras que las mujeres se concentran en niveles de ingreso relativamente más bajos.

Análisis del ingreso por zona (urbana / rural)

A continuación se calcula un resumen del ingreso trimestral por tipo de zona (Zona) utilizando la base filtrada. Este análisis permite explorar diferencias territoriales dentro del rango intermedio de ingresos

ingreso_por_zona <- base_filtrada_sel %>% 
  group_by(Zona) %>% 
  summarise(
    n              = n(),
    ingreso_medio  = mean(ingreso, na.rm = TRUE),
    mediana        = median(ingreso, na.rm = TRUE),
    sd_ingreso     = sd(ingreso, na.rm = TRUE),
    q1             = quantile(ingreso, 0.25, na.rm = TRUE),
    q3             = quantile(ingreso, 0.75, na.rm = TRUE)
  )

ingreso_por_zona
## # A tibble: 3 × 7
##   Zona       n ingreso_medio mediana sd_ingreso    q1     q3
##   <chr>  <int>         <dbl>   <dbl>      <dbl> <dbl>  <dbl>
## 1 Centro 59144        12463.  11739.      7454. 5870. 17705.
## 2 Norte  42673        13588.  13109.      7711. 6677. 19180.
## 3 Sur    24943        10627.   8804.      7112. 4721. 14754.

Realizamos una gráfica de barras con el ingreso promedio por zona, lo que facilita la comparación visual entre áreas urbanas y rurales.

ggplot(ingreso_por_zona, aes(x = Zona, y = ingreso_medio, fill = Zona)) +
  geom_col(alpha = 0.8) +
  scale_y_continuous(labels = scales::comma) +
  labs(
    title = "Ingreso trimestral promedio por zona\n(> 1er cuartil y ≤ 30,000)",
    x = "Zona",
    y = "Ingreso promedio",
    fill = "Zona"
  ) +
  theme_classic()

Al analizar el ingreso por zona geográfica, también se observan diferencias importantes. La zona Norte presenta el ingreso promedio más alto (13,588 pesos) y una mediana cercana a 13,109 pesos, seguida de la zona Centro, con un promedio de 12,463 pesos y mediana de 11,739 pesos.

La zona Sur se ubica por debajo de ambos casos, con un ingreso promedio de 10,627 pesos y una mediana cercana a 8,804 pesos. Los rangos intercuartílicos refuerzan esta jerarquía: Norte y Centro tienen cuartiles más altos y distribuciones más extendidas hacia la parte alta del intervalo (Q3 alrededor de 19,180 y 17,705 pesos, respectivamente), mientras que en el Sur los hogares se concentran en tramos de ingreso más bajos (Q3 ≈ 14,754). En conjunto, dentro del segmento medio de la distribución de ingresos, la localización territorial sigue marcando desigualdades claras entre Norte, Centro y Sur.

Análisis del ingreso por grupos de edad

Ahora se construye una clasificación simple de grupos de edad utilizando mutate() y case_when(). Esto permite comparar el ingreso trimestral entre etapas del ciclo de vida, dentro del rango filtrado de ingresos.

base_edad <- base_filtrada_sel %>% 
  mutate(grupo_edad = case_when(
    edad < 18              ~ "Menores de 18",
    edad >= 18 & edad < 30 ~ "18-29",
    edad >= 30 & edad < 45 ~ "30-44",
    edad >= 45 & edad < 65 ~ "45-64",
    edad >= 65             ~ "65 y más",
    TRUE                   ~ "Sin especificar"
  ))

Calculamos un resumen del ingreso trimestral por grupo de edad dentro de la base filtrada.

ingreso_por_edad <- base_edad %>% 
  group_by(grupo_edad) %>% 
  summarise(
    n              = n(),
    ingreso_medio  = mean(ingreso, na.rm = TRUE),
    mediana        = median(ingreso, na.rm = TRUE),
    sd_ingreso     = sd(ingreso, na.rm = TRUE)
  ) %>% 
  arrange(factor(grupo_edad,
                 levels = c("Menores de 18", "18-29", "30-44", "45-64", "65 y más", "Sin especificar")))

ingreso_por_edad
## # A tibble: 5 × 5
##   grupo_edad        n ingreso_medio mediana sd_ingreso
##   <chr>         <int>         <dbl>   <dbl>      <dbl>
## 1 Menores de 18  7563         6623.   4721.      4647.
## 2 18-29         31431        13035.  12326.      7185.
## 3 30-44         34834        14571.  14242.      7566.
## 4 45-64         34251        13322.  12295.      7569.
## 5 65 y más      18681         8479.   6457.      6280.

Realizamos un gráfico de violín del ingreso trimestral por grupo de edad, utilizando la base filtrada. Este gráfico muestra la forma de la distribución dentro de cada grupo etario.

ggplot(base_edad, aes(x = grupo_edad, y = ingreso)) +
  geom_violin(fill = "plum", alpha = 0.6, trim = TRUE) +
  scale_y_continuous(labels = scales::comma) +
  labs(
    title = "Distribución del ingreso por grupo de edad\n(> 1er cuartil y ≤ 30,000)",
    x = "Grupo de edad",
    y = "Ingreso trimestral"
  ) +
  theme_classic()

La comparación por grupos de edad muestra un patrón muy cercano al ciclo de vida laboral. Los ingresos más altos se observan entre los 30 y 44 años, con un promedio de 14,571 pesos y una mediana de 14,242 pesos, seguidos de los grupos de 18–29 años (promedio = 13,034.636; mediana = 12,326.08 ) y 45–64 años (promedio ≈ 13,321.957; mediana = 12,295.08).

En contraste, los menores de 18 años y las personas de 65 años y más presentan ingresos típicamente más bajos: promedios de alrededor de 6,623 y 8,479 pesos, con medianas cercanas a 4,721 y 6,457 pesos, respectivamente. La desviación estándar también es menor en los extremos de edad, lo que indica que, además de percibir menos, estos grupos se concentran en rangos relativamente estrechos de ingreso.

En síntesis, dentro del tramo intermedio de la distribución, los hogares encabezados por personas en edades activas (sobre todo 30–44 años) son los que concentran los niveles de ingreso más altos, mientras que los más jóvenes y los adultos mayores se ubican en posiciones más desfavorables.

Conclusiones

En la ENIGH, el ingreso trimestral presenta una distribución muy asimétrica: muchos hogares con ingresos bajos y medios conviven con unos pocos casos extremadamente altos, lo que eleva la media y alarga la cola derecha. Por ello se trabajó con una muestra filtrada (ingresos mayores al primer cuartil y ≤ 30 000 pesos), donde el ingreso típico se ubica alrededor de 11 700 pesos y la mayoría de los hogares se concentra entre unos 5 800 y 17 700 pesos trimestrales, manteniendo aún una dispersión considerable dentro de este “segmento medio” de la distribución.

Incluso en esta muestra acotada persisten brechas claras: los hombres tienen ingresos medios y medianos mayores que las mujeres; la zona Norte presenta los niveles de ingreso más altos, seguida de la Centro, mientras que la Sur se mantiene rezagada; y los grupos en edades laborales centrales (especialmente 30–44 años) concentran los ingresos más elevados, frente a menores de 18 y adultos mayores, que se ubican en la parte baja del rango.

En conjunto, los resultados muestran que, aun dejando fuera los extremos de la distribución, el ingreso de los hogares sigue marcado por desigualdades asociadas al género, al territorio y al ciclo de vida, lo que sugiere la importancia de considerar estas dimensiones al diseñar políticas orientadas a mejorar el bienestar económico de la población.