1 Introducción

En este laboratorio aprenderemos a estimar la pobreza por ingresos en México utilizando los microdatos de la Encuesta Nacional de Ingresos y Gastos de los Hogares (ENIGH) 2024, publicada por el INEGI.

Trabajaremos con el archivo concentradohogar.csv, que contiene una fila por hogar con información sobre ingresos, gastos, características del jefe(a) del hogar y localización geográfica.

A lo largo del laboratorio cubriremos:

  1. Carga y exploración de datos
  2. Declaración del diseño muestral complejo
  3. Comparación de estimaciones con y sin ponderadores
  4. Distribución y desigualdad del ingreso (deciles, Gini)
  5. Construcción de líneas de pobreza y clasificación de hogares
  6. Análisis por entidad federativa y zona urbano/rural
  7. Composición del gasto de los hogares
  8. Introducción a la inferencia bayesiana aplicada a la pobreza

Nota importante sobre la ENIGH: La encuesta no es una muestra aleatoria simple. Utiliza un diseño complejo con estratos, conglomerados y factores de expansión. Ignorar esto genera estimaciones incorrectas. Por eso usaremos los paquetes survey y srvyr.


2 Instalación y carga de paquetes

2.1 Instalación (solo la primera vez)

# Ejecuta este bloque UNA SOLA VEZ en tu computadora.
# Después puedes comentarlo con # para no repetir la instalación.
# install.packages(c(
#  "tidyr", "readr", "ggplot2", "dplyr", "scales",
#  "survey", "srvyr", "foreign", "reldist", "ggthemes",
#  "purrr", "bayesplot", "tidybayes", "forcats"
# ))

# Instalación de RStan (motor bayesiano):
# Consulta las instrucciones oficiales en: https://mc-stan.org/install/
# remotes::install_github("stan-dev/rstan", ref = "develop", subdir = "rstan/rstan")
# Una vez instalado RStan, instala rstanarm:
# install.packages("rstanarm")

2.2 Carga de paquetes

# Cada paquete tiene un propósito específico:
library(tidyr)      # Transformación de datos (pivot_longer, pivot_wider)
library(readr)      # Lectura eficiente de archivos CSV
library(dplyr)      # Manipulación de datos (mutate, filter, group_by, etc.)
library(ggplot2)    # Visualizaciones con la gramática de gráficos
library(scales)     # Formatos para ejes (porcentajes, moneda, etc.)
library(survey)     # Análisis con diseños muestrales complejos
library(srvyr)      # Interfaz "tidyverse" para el paquete survey
library(reldist)    # Cálculo del coeficiente de Gini
library(foreign)    # Lectura de archivos de otros softwares estadísticos
library(ggthemes)   # Temas adicionales para ggplot2
library(forcats)    # Manejo de variables categóricas (factores)
library(purrr)      # Programación funcional (map, reduce, etc.)
library(bayesplot)  # Visualizaciones para modelos bayesianos
library(tidybayes)  # Extracción de resultados bayesianos en formato tidy

3 Carga y exploración inicial de datos

3.1 Directorio de trabajo y lectura del archivo

# Establece la carpeta donde están tus archivos de datos.
# Cambia esta ruta a la ubicación correcta en tu computadora.
setwd("~/Documents/Cursos-R/Laboratorio-3")

# Leemos el archivo principal de la ENIGH.
# Cada fila representa un hogar en México.
conc <- read_csv("concentradohogar.csv")

3.2 Exploración rápida

# glimpse() es como una "fotografía" del dataframe:
# muestra el número de filas/columnas, el tipo de cada variable y sus primeros valores.
glimpse(conc)
## Rows: 91,414
## Columns: 126
## $ folioviv   <chr> "0100001901", "0100001902", "0100001904", "0100001905", "01…
## $ foliohog   <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,…
## $ ubica_geo  <chr> "01001", "01001", "01001", "01001", "01001", "01001", "0100…
## $ tam_loc    <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,…
## $ est_socio  <dbl> 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4,…
## $ est_dis    <chr> "001", "001", "001", "001", "002", "002", "002", "002", "00…
## $ upm        <chr> "0000001", "0000001", "0000001", "0000001", "0000002", "000…
## $ factor     <dbl> 207, 207, 207, 207, 196, 196, 196, 196, 196, 213, 213, 213,…
## $ clase_hog  <dbl> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,…
## $ sexo_jefe  <dbl> 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1,…
## $ edad_jefe  <dbl> 32, 48, 60, 43, 29, 30, 28, 33, 48, 55, 50, 28, 23, 23, 75,…
## $ educa_jefe <chr> "06", "09", "06", "08", "08", "08", "06", "09", "10", "04",…
## $ tot_integ  <dbl> 4, 4, 2, 4, 4, 4, 4, 4, 3, 4, 3, 3, 2, 2, 2, 4, 4, 3, 5, 3,…
## $ hombres    <dbl> 2, 2, 1, 3, 1, 3, 2, 1, 1, 3, 2, 2, 1, 1, 1, 2, 1, 1, 3, 2,…
## $ mujeres    <dbl> 2, 2, 1, 1, 3, 1, 2, 3, 2, 1, 1, 1, 1, 1, 1, 2, 3, 2, 2, 1,…
## $ mayores    <dbl> 2, 4, 2, 4, 2, 3, 2, 2, 2, 4, 3, 2, 2, 2, 2, 4, 2, 2, 5, 2,…
## $ menores    <dbl> 2, 0, 0, 0, 2, 1, 2, 2, 1, 0, 0, 1, 0, 0, 0, 0, 2, 1, 0, 1,…
## $ p12_64     <dbl> 2, 4, 2, 4, 2, 3, 2, 2, 2, 4, 3, 2, 2, 2, 1, 4, 2, 2, 5, 2,…
## $ p65mas     <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,…
## $ ocupados   <dbl> 2, 2, 2, 3, 2, 3, 2, 1, 1, 2, 2, 2, 1, 1, 0, 4, 2, 2, 3, 1,…
## $ percep_ing <dbl> 2, 2, 2, 3, 2, 3, 2, 1, 2, 3, 2, 2, 2, 2, 2, 4, 2, 2, 4, 2,…
## $ perc_ocupa <dbl> 2, 2, 2, 3, 2, 3, 2, 1, 1, 2, 2, 2, 1, 1, 0, 4, 2, 2, 3, 1,…
## $ ing_cor    <dbl> 138232.38, 118014.04, 46866.32, 110430.10, 99494.12, 119559…
## $ ingtrab    <dbl> 130518.10, 103829.72, 45580.61, 97169.95, 93687.67, 110484.…
## $ trabajo    <dbl> 130518.10, 103829.72, 45580.61, 97169.95, 93687.67, 110484.…
## $ sueldos    <dbl> 78299.99, 76304.34, 41086.94, 70923.89, 57975.64, 76010.86,…
## $ horas_extr <dbl> 18195.64, 0.00, 0.00, 586.95, 1956.52, 5502.71, 0.00, 0.00,…
## $ comisiones <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 1173.91, 10907.60, 35266.30, …
## $ aguinaldo  <dbl> 9048.90, 9782.60, 122.28, 3668.47, 13695.64, 6603.24, 489.1…
## $ indemtrab  <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 2445.65, 0.…
## $ otra_rem   <dbl> 4402.17, 0.00, 0.00, 4402.17, 6945.64, 20062.14, 0.00, 0.00…
## $ remu_espec <dbl> 20571.40, 17742.78, 4371.39, 17588.47, 13114.23, 1131.40, 1…
## $ negocio    <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,…
## $ noagrop    <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,…
## $ industria  <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ comercio   <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ servicios  <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,…
## $ agrope     <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ agricolas  <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ pecuarios  <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ reproducc  <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ pesca      <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ otros_trab <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 2934.78, 7581.51,…
## $ rentas     <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,…
## $ utilidad   <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,…
## $ arrenda    <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,…
## $ transfer   <dbl> 7714.28, 2571.42, 1285.71, 195.64, 0.00, 1816.76, 5914.27, …
## $ jubilacion <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,…
## $ becas      <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ donativos  <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,…
## $ remesas    <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 978.26, 0.0…
## $ bene_gob   <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 3049.…
## $ transf_hog <dbl> 7714.28, 2571.42, 1285.71, 0.00, 0.00, 1816.76, 5914.27, 0.…
## $ trans_inst <dbl> 0.00, 0.00, 0.00, 195.64, 0.00, 0.00, 0.00, 0.00, 5629.99, …
## $ estim_alqu <dbl> 0.00, 11612.90, 0.00, 13064.51, 5806.45, 7258.06, 5806.45, …
## $ otros_ing  <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ gasto_mon  <dbl> 47478.66, 38782.74, 28601.26, 43509.83, 132552.40, 74443.10…
## $ alimentos  <dbl> 17858.49, 22384.13, 9382.81, 23682.69, 39207.49, 25006.83, …
## $ ali_dentro <dbl> 8421.36, 13641.30, 9382.81, 23682.69, 38178.93, 21394.03, 1…
## $ cereales   <dbl> 809.99, 1079.96, 2005.70, 4152.83, 4840.66, 1555.68, 1607.1…
## $ carnes     <dbl> 835.70, 4114.27, 1928.56, 4782.84, 5804.95, 2571.41, 385.70…
## $ pescado    <dbl> 0.00, 0.00, 0.00, 0.00, 501.42, 0.00, 0.00, 977.14, 0.00, 0…
## $ leche      <dbl> 1954.28, 1182.84, 1131.41, 3162.83, 4339.24, 835.70, 128.57…
## $ huevo      <dbl> 385.71, 0.00, 617.14, 1465.71, 482.14, 308.57, 989.99, 321.…
## $ aceites    <dbl> 0.00, 2314.28, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 80…
## $ tuberculo  <dbl> 0.00, 385.71, 0.00, 707.13, 257.14, 437.14, 0.00, 0.00, 359…
## $ verduras   <dbl> 347.13, 964.27, 1115.73, 2378.54, 2809.22, 1607.11, 681.41,…
## $ frutas     <dbl> 0.00, 0.00, 128.57, 694.28, 1992.83, 1028.54, 0.00, 2095.69…
## $ azucar     <dbl> 0.00, 0.00, 642.85, 0.00, 0.00, 0.00, 0.00, 269.99, 0.00, 0…
## $ cafe       <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 128.57, 205.71, 0…
## $ especias   <dbl> 0.00, 0.00, 527.14, 0.00, 327.85, 282.85, 192.85, 0.00, 0.0…
## $ otros_alim <dbl> 3728.56, 2571.42, 1285.71, 4641.41, 13731.39, 9887.11, 1297…
## $ bebidas    <dbl> 359.99, 1028.55, 0.00, 1697.12, 3092.09, 2879.92, 2327.09, …
## $ ali_fuera  <dbl> 9437.13, 8742.83, 0.00, 0.00, 1028.56, 2892.84, 0.00, 0.00,…
## $ tabaco     <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 719.96, 0.00, 0.00, 0.00, 0.0…
## $ vesti_calz <dbl> 635.86, 0.00, 0.00, 2885.85, 19639.48, 4008.86, 6035.84, 46…
## $ vestido    <dbl> 0.00, 0.00, 0.00, 2885.85, 11915.15, 3617.56, 0.00, 469.56,…
## $ calzado    <dbl> 635.86, 0.00, 0.00, 0.00, 7724.33, 391.30, 6035.84, 0.00, 0…
## $ vivienda   <dbl> 6475.63, 1990.00, 4731.86, 1873.96, 2062.14, 1980.96, 877.5…
## $ alquiler   <dbl> 4354.83, 0.00, 2903.22, 0.00, 0.00, 0.00, 0.00, 0.00, 7258.…
## $ pred_cons  <dbl> 0.0, 100.0, 0.0, 137.5, 0.0, 0.0, 0.0, 102.5, 0.0, 162.5, 2…
## $ agua       <dbl> 1200, 990, 585, 591, 1000, 735, 600, 756, 855, 690, 1650, 9…
## $ energia    <dbl> 920.80, 900.00, 1243.64, 1145.46, 1062.14, 1245.96, 277.50,…
## $ limpieza   <dbl> 3811.92, 1637.39, 966.74, 1184.48, 6590.25, 2786.54, 1590.9…
## $ cuidados   <dbl> 3811.92, 1637.39, 966.74, 1184.48, 6590.25, 2743.50, 1590.9…
## $ utensilios <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 43.04, 0.00, 0.00, 645.64, 0.…
## $ enseres    <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 1829.33, 90…
## $ salud      <dbl> 0.00, 0.00, 1128.91, 19.56, 7767.35, 6104.31, 0.00, 27838.3…
## $ ambul_serv <dbl> 0.00, 0.00, 489.13, 0.00, 4108.68, 2347.81, 0.00, 0.00, 0.0…
## $ aten_hosp  <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 2152.17, 0.00, 25434.78, 0.00…
## $ medic_prod <dbl> 0.00, 0.00, 639.78, 19.56, 3658.67, 1604.33, 0.00, 2403.56,…
## $ transporte <dbl> 9929.03, 8796.76, 11009.03, 7068.64, 8296.94, 12314.75, 378…
## $ publico    <dbl> 0.00, 0.00, 0.00, 192.85, 5335.65, 0.00, 809.97, 0.00, 1484…
## $ foraneo    <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 508.69, 0.0…
## $ adqui_vehi <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 68478.26, 0.00, 0…
## $ mantenim   <dbl> 6967.74, 4354.83, 6967.74, 3483.86, 0.00, 9430.11, 0.00, 11…
## $ refaccion  <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 1301.08, 0.00, 0.00, 0.00, 0.…
## $ combus     <dbl> 6967.74, 4354.83, 6967.74, 3483.86, 0.00, 8129.03, 0.00, 11…
## $ comunica   <dbl> 2961.29, 4441.93, 4041.29, 3391.93, 2961.29, 2884.64, 2970.…
## $ educa_espa <dbl> 8651.61, 839.02, 0.00, 4239.86, 16040.42, 2676.00, 2496.77,…
## $ educacion  <dbl> 8651.61, 0.00, 0.00, 88.04, 8736.16, 2676.00, 2496.77, 290.…
## $ esparci    <dbl> 0.00, 839.02, 0.00, 4151.82, 5934.70, 0.00, 0.00, 2891.81, …
## $ paq_turist <dbl> 0.00, 0.00, 0.00, 0.00, 1369.56, 0.00, 0.00, 0.00, 9205.43,…
## $ personales <dbl> 116.12, 3135.44, 1381.91, 2554.79, 22825.56, 3619.21, 1828.…
## $ cuida_pers <dbl> 116.12, 3135.44, 1381.91, 2554.79, 21878.61, 2885.75, 1828.…
## $ acces_pers <dbl> 0.00, 0.00, 0.00, 0.00, 898.04, 518.46, 0.00, 0.00, 0.00, 0…
## $ otros_gas  <dbl> 0.00, 0.00, 0.00, 0.00, 48.91, 215.00, 0.00, 7500.00, 146.7…
## $ transf_gas <dbl> 0.00, 0.00, 0.00, 0.00, 10122.77, 15945.64, 0.00, 2690.21, …
## $ percep_tot <dbl> 13499.97, 0.00, 5435.96, 6847.82, 35706.51, 2934.78, 0.00, …
## $ retiro_inv <dbl> 0.00, 0.00, 0.00, 0.00, 35706.51, 2934.78, 0.00, 26657.60, …
## $ prestamos  <dbl> 0.00, 0.00, 0.00, 6847.82, 0.00, 0.00, 0.00, 29347.82, 0.00…
## $ otras_perc <dbl> 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 220.1, 0.0, 0.0, 0.…
## $ ero_nm_viv <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ ero_nm_hog <dbl> 13499.97, 0.00, 5435.96, 0.00, 0.00, 0.00, 0.00, 2571.42, 0…
## $ erogac_tot <dbl> 29582.60, 8709.67, 4695.65, 22768.99, 16145.46, 14757.53, 9…
## $ cuota_viv  <dbl> 0.00, 8709.67, 0.00, 0.00, 6096.77, 5806.45, 9580.64, 0.00,…
## $ mater_serv <dbl> 0.00, 0.00, 0.00, 366.84, 0.00, 0.00, 0.00, 0.00, 0.00, 295…
## $ material   <dbl> 0.00, 0.00, 0.00, 366.84, 0.00, 0.00, 0.00, 0.00, 0.00, 0.0…
## $ servicio   <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 295.0…
## $ deposito   <dbl> 21365.21, 0.00, 4695.65, 5869.56, 0.00, 0.00, 0.00, 0.00, 0…
## $ prest_terc <dbl> 0.00, 0.00, 0.00, 0.00, 2934.78, 0.00, 0.00, 0.00, 0.00, 0.…
## $ pago_tarje <dbl> 0.00, 0.00, 0.00, 7336.95, 0.00, 3081.52, 0.00, 0.00, 0.00,…
## $ deudas     <dbl> 8217.39, 0.00, 0.00, 2934.78, 0.00, 0.00, 0.00, 0.00, 0.00,…
## $ balance    <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ otras_erog <dbl> 0.00, 0.00, 0.00, 6260.86, 7113.91, 5869.56, 0.00, 4989.13,…
## $ smg        <dbl> 22403.7, 22403.7, 22403.7, 22403.7, 22403.7, 22403.7, 22403…
# Dimensiones del dataset: filas = hogares, columnas = variables
dim(conc)
## [1] 91414   126
# Nombres de todas las variables disponibles
names(conc)
##   [1] "folioviv"   "foliohog"   "ubica_geo"  "tam_loc"    "est_socio" 
##   [6] "est_dis"    "upm"        "factor"     "clase_hog"  "sexo_jefe" 
##  [11] "edad_jefe"  "educa_jefe" "tot_integ"  "hombres"    "mujeres"   
##  [16] "mayores"    "menores"    "p12_64"     "p65mas"     "ocupados"  
##  [21] "percep_ing" "perc_ocupa" "ing_cor"    "ingtrab"    "trabajo"   
##  [26] "sueldos"    "horas_extr" "comisiones" "aguinaldo"  "indemtrab" 
##  [31] "otra_rem"   "remu_espec" "negocio"    "noagrop"    "industria" 
##  [36] "comercio"   "servicios"  "agrope"     "agricolas"  "pecuarios" 
##  [41] "reproducc"  "pesca"      "otros_trab" "rentas"     "utilidad"  
##  [46] "arrenda"    "transfer"   "jubilacion" "becas"      "donativos" 
##  [51] "remesas"    "bene_gob"   "transf_hog" "trans_inst" "estim_alqu"
##  [56] "otros_ing"  "gasto_mon"  "alimentos"  "ali_dentro" "cereales"  
##  [61] "carnes"     "pescado"    "leche"      "huevo"      "aceites"   
##  [66] "tuberculo"  "verduras"   "frutas"     "azucar"     "cafe"      
##  [71] "especias"   "otros_alim" "bebidas"    "ali_fuera"  "tabaco"    
##  [76] "vesti_calz" "vestido"    "calzado"    "vivienda"   "alquiler"  
##  [81] "pred_cons"  "agua"       "energia"    "limpieza"   "cuidados"  
##  [86] "utensilios" "enseres"    "salud"      "ambul_serv" "aten_hosp" 
##  [91] "medic_prod" "transporte" "publico"    "foraneo"    "adqui_vehi"
##  [96] "mantenim"   "refaccion"  "combus"     "comunica"   "educa_espa"
## [101] "educacion"  "esparci"    "paq_turist" "personales" "cuida_pers"
## [106] "acces_pers" "otros_gas"  "transf_gas" "percep_tot" "retiro_inv"
## [111] "prestamos"  "otras_perc" "ero_nm_viv" "ero_nm_hog" "erogac_tot"
## [116] "cuota_viv"  "mater_serv" "material"   "servicio"   "deposito"  
## [121] "prest_terc" "pago_tarje" "deudas"     "balance"    "otras_erog"
## [126] "smg"

¿Qué estás viendo? La ENIGH 2024 contiene miles de hogares y decenas de variables. Las más importantes para este laboratorio son:

  • ing_cor: ingreso corriente trimestral del hogar (en pesos)
  • gasto_mon: gasto monetario trimestral del hogar
  • tot_integ: número de integrantes del hogar
  • factor: factor de expansión (cuántos hogares representa cada fila en la población)
  • upm: Unidad Primaria de Muestreo (conglomerado)
  • est_dis: estrato de diseño muestral

4 Diseño muestral complejo

La ENIGH utiliza un muestreo probabilístico estratificado y por conglomerados. Para obtener estimaciones correctas debemos declarar este diseño explícitamente en R.

# Declaramos el diseño muestral con as_survey_design() del paquete srvyr.
# Argumentos:
#   ids     = upm      → Unidades Primarias de Muestreo (conglomerados/clústeres)
#   strata  = est_dis  → Estratos de diseño
#   weights = factor   → Factores de expansión poblacional
#   nest    = TRUE     → Indica que las UPM están anidadas dentro de los estratos
diseno <- conc %>%
  as_survey_design(
    ids     = upm,
    strata  = est_dis,
    weights = factor,
    nest    = TRUE
  )

# Resumen del diseño: verifica que esté correctamente especificado
summary(diseno)
## Stratified 1 - level Cluster Sampling design (with replacement)
## With (10569) clusters.
## Called via srvyr
## Probabilities:
##      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
## 0.0001403 0.0019011 0.0034722 0.0070662 0.0070922 0.2500000 
## Stratum Sizes: 
##            001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016  017
## obs        497 487 383  32  65  20  38  95  68  74  53  18  12  29  10  10 1019
## design.PSU  91  84  73   6   5   5   4   8   3   3   9   4   2   2   2   2   48
## actual.PSU  91  84  73   6   5   5   4   8   3   3   9   4   2   2   2   2   48
##            018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033  034
## obs         52  90  53  44 168 133 149  69  41 269 179 453  30  67 135  22 1303
## design.PSU   9  16  11   2  34  30  28   4   2  57  43  86   6   3   8   4   68
## actual.PSU   9  16  11   2  34  30  28   4   2  57  43  86   6   3   8   4   68
##            035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051
## obs         23 768  96  87  65  77 254 314  90  25  17 266 110 112 252 149 399
## design.PSU   5  36   4   4   3   5  50  59  16   3   3  56  31  25  48   7  19
## actual.PSU   5  36   4   4   3   5  50  59  16   3   3  56  31  25  48   7  19
##            052 053 054 055 056 057 058 059 060 061 062 063 064 065 066 067 068
## obs        490 166 139 120 243  90  93 226  12  24  73 234  69 111  68  69  41
## design.PSU  22   9   6   7  48  19   5  45   3   5  13  43  18  21   3   3   2
## actual.PSU  22   9   6   7  48  19   5  45   3   5  13  43  18  21   3   3   2
##            069 070 071 072 073 074 075 076 077 078 079 080 081 082 083 084 085
## obs        452  38 167 226   9   6  50 162  25  52  45  17  21  37 133  87  85
## design.PSU  20   8  30  13   2   2   3  11   6  10   9   3   4  11  28  17   4
## actual.PSU  20   8  30  13   2   2   3  11   6  10   9   3   4  11  28  17   4
##            086 087 088 089 090 091 092 093 094 095 096 097 098 099 100 101 102
## obs        115  59  27 439 378 188  59 319 310 188 775  25   9  64  42  66  65
## design.PSU  24  13   6  91  75  50   3  62  64  44  36   2   2   3   2   3   3
## actual.PSU  24  13   6  91  75  50   3  62  64  44  36   2   2   3   2   3   3
##            103 104 105 106 107 108 109 110 111  112 113 114 115 116 117 118 119
## obs        287 424 174  43 135 146 256  10  54 1050 168  40  41 266  84 122 120
## design.PSU  56  85  41   2  11  32  52   2  12   50   8   2   2  13   4   6   6
## actual.PSU  56  85  41   2  11  32  52   2  12   50   8   2   2  13   4   6   6
##            120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
## obs        121 968 156   8  33  10  11  10  29  16  37  71  31  42  23  18 106
## design.PSU   7  45   8   2   6   2   2   2   5   3   7   4   6   9   5   5  20
## actual.PSU   7  45   8   2   6   2   2   2   5   3   7   4   6   9   5   5  20
##            137 138 139 140 141 142 143 144 145 146 147  148 149 150 151 152 153
## obs         72  28 143  45 128  65  68 108  65  18  31 1231 309 186 313  11  12
## design.PSU  15   5   7   2   9   3   4   5  12   4   7   59  62  35  63   2   3
## actual.PSU  15   5   7   2   9   3   4   5  12   4   7   59  62  35  63   2   3
##            154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
## obs         45  59  33  47  14 748 361 216  16  45  42 590 746 415 796  27  15
## design.PSU   8  11   6   9   3 137  70  48   3   2   2  27 158  75 150   5   3
## actual.PSU   8  11   6   9   3 137  70  48   3   2   2  27 158  75 150   5   3
##            171 172 173 174 175 176 177 178 179 180  181 182 183 184 185 186 187
## obs          9  10 215 343  37  79 292 145 240   8 1038 181 139  36 107 121  50
## design.PSU   2   2  10  16   2   5  57  32  47   2   50  35  27   8   5   7   9
## actual.PSU   2   2  10  16   2   5  57  32  47   2   50  35  27   8   5   7   9
##            188 189 190 191 192 193 194 195 196  197 198 199 200 201 202 203 204
## obs         12  46  17 236 111 106  29  50  47 1471  77  40 102  63  27   8  10
## design.PSU   2   9   4  11   5   7   6  10   9   71   5   2   6   4   5   2   2
## actual.PSU   2   9   4  11   5   7   6  10   9   71   5   2   6   4   5   2   2
##            205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
## obs         29  41  83 290  17  85 128  10  35  18  20   9   7 208  10  83 193
## design.PSU   6   9  14  51   3  21  24   2   7   4   4   2   2   9   2  18  44
## actual.PSU   6   9  14  51   3  21  24   2   7   4   4   2   2   9   2  18  44
##            222 223 224 225 226 227 228 229 230 231 232 233 234  235 236 237 238
## obs         90 100  10 123  62 106 107  12  65  18  35  36  16 1054  37  47  96
## design.PSU  21   5   3   6   3   5   5   3  13   3   8   7   3   49   7   2   5
## actual.PSU  21   5   3   6   3   5   5   3  13   3   8   7   3   49   7   2   5
##            239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
## obs        191 122 147  52  30  21 375 744 213  47 119  63  90  65  27  13  14
## design.PSU   9   7   8   4   6   4  17  39  15   2  10  15  18  12   6   3   3
## actual.PSU   9   7   8   4   6   4  17  39  15   2  10  15  18  12   6   3   3
##            256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
## obs         22  30  10  42  45  50  19  10 210  77  63 134 292 337 333  42  15
## design.PSU   5   3   2   2   8   3   4   2  18   7   3  12  68  67  73   6   3
## actual.PSU   5   3   2   2   8   3   4   2  18   7   3  12  68  67  73   6   3
##            273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
## obs          9  63  13  32   9 619  43  21  24  44  13  28  43  61  60  32  26
## design.PSU   2   6   3   7   2  32   9   4   6   3   3   5   7   3  11   5   6
## actual.PSU   2   6   3   7   2  32   9   4   6   3   3   5   7   3  11   5   6
##            290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306
## obs         22 446 590 209  96  25  19  79  90  48  18  18 802  13  21  32  42
## design.PSU   5  83 103  43   8   2   4  14  10   6   3   4  41   3   6   6   7
## actual.PSU   5  83 103  43   8   2   4  14  10   6   3   4  41   3   6   6   7
##            307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323
## obs         46 797  12  11   9  10 169  27  15  82  48 143 133  34  22  43  29
## design.PSU   8  37   2   2   2   2  10   6   3   4   2   7   6   7   4   2   3
## actual.PSU   8  37   2   2   2   2  10   6   3   4   2   7   6   7   4   2   3
##            324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340
## obs        144  85  94  11  90  45 531  75  56  53 201 102 200  30 322  28  62
## design.PSU  30  19  18   2   5   2  26  14  11  10   9   6  21   4  20   2   5
## actual.PSU  30  19  18   2   5   2  26  14  11  10   9   6  21   4  20   2   5
##            341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
## obs         28  23  54  97  22 498 290 271   8  23 110   9  22  23  24  60  10
## design.PSU   2   4  11  18   4  25  60  50   2   4  25   2   5   5   5  12   2
## actual.PSU   2   4  11  18   4  25  60  50   2   4  25   2   5   5   5  12   2
##            358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374
## obs         24 122  41  55 124 158 240 200  16  21  46  25  46 315 143 153 516
## design.PSU   5   7   2   3   6   8  11   9   3   4   8   2   2  63  26  29  25
## actual.PSU   5   7   2   3   6   8  11   9   3   4   8   2   2  63  26  29  25
##            375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391
## obs        121 164 471  19  37 533 494  28  29  34  37  76  59  91  42  10  36
## design.PSU   6  17 112   4   4 105  91   2   3   2   2  14   3  18   9   2   8
## actual.PSU   6  17 112   4   4 105  91   2   3   2   2  14   3  18   9   2   8
##            392 393  394 395 396 397 398 399 400 401 402 403 404 405 406 407 408
## obs         11  17 1207  55 346  86  69  15  83 111 322 102  46  15  46   8  33
## design.PSU   2   4   63   3  17   4   4   3   5   5  15   5   3   3  10   2   9
## actual.PSU   2   4   63   3  17   4   4   3   5   5  15   5   3   3  10   2   9
##            409 410 411  412 413 414 415 416 417 418 419 420 421 422 423 424 425
## obs          9   8  28 1341  60 113  11  20  10  40  15  24  29 151  63  11  12
## design.PSU   2   2   6   62  13   5   2   5   2   8   3   5   2   8  12   2   2
## actual.PSU   2   2   6   62  13   5   2   5   2   8   3   5   2   8  12   2   2
##            426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442
## obs         39  31  27  16  39  92 112  40 100  92 270 157  16 163  42  50  25
## design.PSU   2   8   5   4   8   4   5   2   5   4  56  31   3  38   2   9   5
## actual.PSU   2   8   5   4   8   4   5   2   5   4  56  31   3  38   2   9   5
##            443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459
## obs         15 410 225  26 318  35  51 357  33  41  11 159 186  81  57  19  15
## design.PSU   3  18  10   3  65   7  12  86   8   8   3  32  12   7   6   6   3
## actual.PSU   3  18  10   3  65   7  12  86   8   8   3  32  12   7   6   6   3
##            460 461  462 463 464 465 466 467 468 469 470 471 472 473 474 475 476
## obs         15  12 1348 132  41  87  72  21 577  90  46  66  43  72 183  24  65
## design.PSU   5   2   62   9   3  18  13   5  26   4   2   3   2   4  36   5  12
## actual.PSU   5   2   62   9   3  18  13   5  26   4   2   3   2   4  36   5  12
##            477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493
## obs         98 568 158 152  35  54 167 133 394  70 135  98 670  88  89  47  58
## design.PSU  18 108  32  36   8  10  31  25  18   3   7   5  33   4   4  10  12
## actual.PSU  18 108  32  36   8  10  31  25  18   3   7   5  33   4   4  10  12
##            494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510
## obs         41 236 394 209  31  11 588 187 108  70  28  89 172 152 527 258 204
## design.PSU   2  57  81  42   3   2  27  38  21  17   2   4  11   7  25  63  40
## actual.PSU   2  57  81  42   3   2  27  38  21  17   2   4  11   7  25  63  40
##            511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527
## obs        432  14  49  88 110  38 147 118 221 221  24  42  97  82  92 132 112
## design.PSU  88   3   2   4   5   2   7  25  44  40   4   2   4   4   4   6  20
## actual.PSU  88   3   2   4   5   2   7  25  44  40   4   2   4   4   4   6  20
##            528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544
## obs         97  48  65  60  39  41  16 234 177 160  66  12  40  38  10  79  92
## design.PSU  18  10   3   3   7   7   3  45  39  29   3   2   7   7   2  14  17
## actual.PSU  18  10   3   3   7   7   3  45  39  29   3   2   7   7   2  14  17
##            545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561
## obs         28  54  68 332 468 101 222  67  91  21  16 560  98 131  15 198 181
## design.PSU   5  11  13  15  21   5  12   3   7   4   3  28  18  26   4  15  11
## actual.PSU   5  11  13  15  21   5  12   3   7   4   3  28  18  26   4  15  11
##            562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578
## obs         50  72  10  53 415 108  32  18 150 162  75  44  44 178  76  15  10
## design.PSU  11  15   2   4  18   5   6   3  28  36  16   2   2  35  17   4   2
## actual.PSU  11  15   2   4  18   5   6   3  28  36  16   2   2  35  17   4   2
##            579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595
## obs         61  53  15 133 241  79  19  18  54  15  49  95  45 386 161 189 364
## design.PSU   3  13   5  28  54  20   4   7  10   3  10  18   9  18   8  41  73
## actual.PSU   3  13   5  28  54  20   4   7  10   3  10  18   9  18   8  41  73
##            596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612
## obs        165 315  91  54  21  67 179  83 111 371 147  16  46  14  22  44 182
## design.PSU  34  61   4   4   4  13  18   4   8  22   7   4   9   3   5   2  13
## actual.PSU  34  61   4   4   4  13  18   4   8  22   7   4   9   3   5   2  13
##            613 614 615 616 617 618 619 620 621 622 623 624 625 626  627 628 629
## obs         17 128  59  69  48  25  51  13  50  63  36  27  29  33 1014  30  15
## design.PSU   3   9  11  13  11   6  13   3   4   3   7   5   6   6   46   6   4
## actual.PSU   3   9  11  13  11   6  13   3   4   3   7   5   6   6   46   6   4
##            630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646
## obs        590  73  61  16  22  23  17  26  49  30  11  28  14  12  13   9  11
## design.PSU  26   4   4   3   4   3   3   5   3   7   2   5   3   2   3   2   2
## actual.PSU  26   4   4   3   4   3   3   5   3   7   2   5   3   2   3   2   2
##            647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663
## obs         18  18   8 127 145  96  83  86  77 273  39 298 887 213   9  19  14
## design.PSU   3   3   2   6  10   5   4   4   4  61   8  77  41  69   3   4   3
## actual.PSU   3   3   2   6  10   5   4   4   4  61   8  77  41  69   3   4   3
##            664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680
## obs         67  17  77 278 236 185 161 114  87  10 181  66 168 235  21  81 976
## design.PSU  14   4   5  13  11   9   9  22  17   2   8  13  38  44   4   4  43
## actual.PSU  14   4   5  13  11   9   9  22  17   2   8  13  38  44   4   4  43
##            681
## obs         41
## design.PSU   2
## actual.PSU   2
## Data variables:
##   [1] "folioviv"   "foliohog"   "ubica_geo"  "tam_loc"    "est_socio" 
##   [6] "est_dis"    "upm"        "factor"     "clase_hog"  "sexo_jefe" 
##  [11] "edad_jefe"  "educa_jefe" "tot_integ"  "hombres"    "mujeres"   
##  [16] "mayores"    "menores"    "p12_64"     "p65mas"     "ocupados"  
##  [21] "percep_ing" "perc_ocupa" "ing_cor"    "ingtrab"    "trabajo"   
##  [26] "sueldos"    "horas_extr" "comisiones" "aguinaldo"  "indemtrab" 
##  [31] "otra_rem"   "remu_espec" "negocio"    "noagrop"    "industria" 
##  [36] "comercio"   "servicios"  "agrope"     "agricolas"  "pecuarios" 
##  [41] "reproducc"  "pesca"      "otros_trab" "rentas"     "utilidad"  
##  [46] "arrenda"    "transfer"   "jubilacion" "becas"      "donativos" 
##  [51] "remesas"    "bene_gob"   "transf_hog" "trans_inst" "estim_alqu"
##  [56] "otros_ing"  "gasto_mon"  "alimentos"  "ali_dentro" "cereales"  
##  [61] "carnes"     "pescado"    "leche"      "huevo"      "aceites"   
##  [66] "tuberculo"  "verduras"   "frutas"     "azucar"     "cafe"      
##  [71] "especias"   "otros_alim" "bebidas"    "ali_fuera"  "tabaco"    
##  [76] "vesti_calz" "vestido"    "calzado"    "vivienda"   "alquiler"  
##  [81] "pred_cons"  "agua"       "energia"    "limpieza"   "cuidados"  
##  [86] "utensilios" "enseres"    "salud"      "ambul_serv" "aten_hosp" 
##  [91] "medic_prod" "transporte" "publico"    "foraneo"    "adqui_vehi"
##  [96] "mantenim"   "refaccion"  "combus"     "comunica"   "educa_espa"
## [101] "educacion"  "esparci"    "paq_turist" "personales" "cuida_pers"
## [106] "acces_pers" "otros_gas"  "transf_gas" "percep_tot" "retiro_inv"
## [111] "prestamos"  "otras_perc" "ero_nm_viv" "ero_nm_hog" "erogac_tot"
## [116] "cuota_viv"  "mater_serv" "material"   "servicio"   "deposito"  
## [121] "prest_terc" "pago_tarje" "deudas"     "balance"    "otras_erog"
## [126] "smg"

¿Por qué importa el diseño muestral?
El factor de expansión indica cuántos hogares de la población real representa cada hogar entrevistado. Un hogar rural puede representar a 50 hogares similares, mientras que uno urbano puede representar a 200. Si no ponderamos, le damos el mismo peso a todos y las estimaciones nacionales son sesgadas.


5 Ingreso corriente: media ponderada vs. no ponderada

Antes de calcular cualquier indicador, veamos cuán importante es usar los ponderadores correctos.

5.1 Comparación de estimaciones

# INCORRECTO: Media aritmética simple (ignora el diseño muestral)
media_simple <- mean(conc$ing_cor, na.rm = TRUE)

# CORRECTO: Media ponderada usando el diseño muestral
media_pond <- diseno %>%
  summarise(
    media     = survey_mean(ing_cor, na.rm = TRUE),
    total_hog = survey_total(1)   # Número total de hogares que representa la encuesta
  )

cat("=== Comparación de medias del ingreso corriente trimestral ===\n")
## === Comparación de medias del ingreso corriente trimestral ===
cat("Media sin ponderar: $", round(media_simple, 0), "\n")
## Media sin ponderar: $ 72274
cat("Media ponderada:    $", round(media_pond$media, 0), "\n")
## Media ponderada:    $ 77864
cat("Error estándar:     $", round(media_pond$media_se, 0), "\n")
## Error estándar:     $ 606
cat("Total de hogares representados:",
    format(media_pond$total_hog, big.mark = ","), "\n")
## Total de hogares representados: 38,830,230

Interpreta los resultados: Si la media ponderada y la simple difieren de forma importante, significa que el diseño muestral sobre- o sub-representa ciertos tipos de hogares. Siempre debemos usar la media ponderada para inferencias nacionales.

5.2 Estadísticas nacionales del ingreso mensual

# La ENIGH reporta el ingreso de forma trimestral.
# Dividimos entre 3 para obtener el equivalente mensual.

ing_nacional <- diseno %>%
  summarise(
    media   = survey_mean(ing_cor, na.rm = TRUE, vartype = "ci"),  # con intervalo de confianza
    mediana = survey_median(ing_cor, na.rm = TRUE),
    p25     = survey_quantile(ing_cor, quantiles = 0.25, na.rm = TRUE),
    p75     = survey_quantile(ing_cor, quantiles = 0.75, na.rm = TRUE)
  ) %>%
  mutate(across(where(is.numeric), ~ . / 3))  # convertir a mensual

ing_nacional
## # A tibble: 1 × 9
##    media media_low media_upp mediana mediana_se p25_q25 p25_q25_se p75_q75
##    <dbl>     <dbl>     <dbl>   <dbl>      <dbl>   <dbl>      <dbl>   <dbl>
## 1 25955.    25559.    26350.  19739.       94.9  12292.       62.3  31714.
## # ℹ 1 more variable: p75_q75_se <dbl>
cat("\n--- Ingreso corriente MENSUAL promedio por hogar ---\n")
## 
## --- Ingreso corriente MENSUAL promedio por hogar ---
cat("Media:   $", format(round(ing_nacional$media, 0), big.mark = ","), "\n")
## Media:   $ 25,955
cat("IC 95%: [$", format(round(ing_nacional$media_low, 0), big.mark = ","),
    ", $", format(round(ing_nacional$media_upp, 0), big.mark = ","), "]\n")
## IC 95%: [$ 25,559 , $ 26,350 ]

5.3 Distribución del ingreso mensual

# Creamos una nueva variable de ingreso mensual en el diseño muestral
diseno <- diseno %>%
  mutate(ing_mensual = ing_cor / 3)

# Extraemos los datos como data.frame para graficar con ggplot2
df_plot <- diseno %>%
  select(ing_mensual, factor) %>%
  as.data.frame()

# Calculamos media y mediana ponderadas para anotarlas en la gráfica
media_w <- diseno %>%
  summarise(media = survey_mean(ing_mensual, na.rm = TRUE)) %>%
  pull(media)

mediana_w <- diseno %>%
  summarise(mediana = survey_median(ing_mensual, na.rm = TRUE)) %>%
  pull(mediana)

# Histograma con curva de densidad (ponderada)
distribucion_ingreso <- ggplot(df_plot, aes(x = ing_mensual, weight = factor)) +
  geom_histogram(aes(y = after_stat(density)), bins = 80,
                 fill = "forestgreen", alpha = 0.6, color = "white") +
  geom_density(color = "black", lwd = 1, adjust = 1.2) +
  scale_x_continuous(
    labels = scales::comma,
    limits = c(0, quantile(df_plot$ing_mensual, 0.99, na.rm = TRUE))
  ) +
  geom_vline(xintercept = media_w, color = "blue", linetype = "dashed", lwd = 1) +
  geom_vline(xintercept = mediana_w, color = "darkorchid", linetype = "dashed", lwd = 1) +
  annotate("text", x = media_w + 2000, y = 0.00002,
           label = paste("Media:", round(media_w)), color = "blue") +
  annotate("text", x = mediana_w + 2000, y = 0.000018,
           label = paste("Mediana:", round(mediana_w)), color = "darkorchid") +
  labs(
    title = "Distribución del ingreso mensual del hogar (con ponderadores)",
    x = "Ingreso mensual del hogar (MXN)", y = "Densidad"
  ) +
  theme_minimal()

distribucion_ingreso

¿Por qué la mediana es menor que la media? La distribución del ingreso es asimétrica a la derecha: un pequeño grupo de hogares con ingresos muy altos “jala” la media hacia arriba. La mediana es más representativa del hogar “típico” en México.


6 Deciles de ingreso y desigualdad

Los deciles dividen a los hogares en 10 grupos iguales ordenados por ingreso, del más pobre (decil 1) al más rico (decil 10).

6.1 Construcción de deciles con factores de expansión

# Método acumulativo: ordena los hogares por ingreso y asigna deciles
# considerando cuántos hogares reales representa cada fila (factor de expansión).
conc <- conc %>%
  arrange(ing_cor) %>%
  mutate(
    acum_peso    = cumsum(factor),          # peso acumulado
    total_peso   = sum(factor),             # peso total de la población
    decil_ingreso = ceiling(acum_peso / total_peso * 10),  # decil de 1 a 10
    decil_ingreso = pmin(decil_ingreso, 10) # garantiza que el máximo sea 10
  )

# Reconstruimos el diseño con la nueva variable de decil
diseno2 <- conc %>%
  as_survey_design(ids = upm, strata = est_dis, weights = factor, nest = TRUE)

# Ingreso promedio mensual por decil
ing_decil <- diseno2 %>%
  group_by(decil_ingreso) %>%
  summarise(
    ing_prom  = survey_mean(ing_cor, na.rm = TRUE),
    n_hogares = survey_total(1)
  ) %>%
  mutate(ing_prom_mensual = ing_prom / 3)

print(ing_decil)
## # A tibble: 10 × 6
##    decil_ingreso ing_prom ing_prom_se n_hogares n_hogares_se ing_prom_mensual
##            <dbl>    <dbl>       <dbl>     <dbl>        <dbl>            <dbl>
##  1             1   16795.        73.9   3882924       66464.            5598.
##  2             2   28297.        38.3   3883042       58707.            9432.
##  3             3   36844.        37.0   3883010       60125.           12281.
##  4             4   45244.        40.1   3882672       60447.           15081.
##  5             5   54307.        44.3   3883138       62223.           18102.
##  6             6   64599.        50.6   3883019       62210.           21533.
##  7             7   77449.        70.0   3883005       63041.           25816.
##  8             8   95289.        93.6   3882963       61484.           31763.
##  9             9  123710.       176.    3883293       63572.           41237.
## 10            10  236092.      4819.    3883164       68233.           78697.

6.2 Gráfica de ingreso por decil

deciles_ingreso_plot <- ggplot(
  ing_decil,
  aes(x = factor(decil_ingreso), y = ing_prom_mensual, fill = factor(decil_ingreso))
) +
  geom_col(alpha = 0.85) +
  geom_text(
    aes(label = dollar(ing_prom_mensual, prefix = "$", big.mark = ",", accuracy = 1)),
    vjust = -0.4, size = 3
  ) +
  scale_y_continuous(labels = dollar_format(prefix = "$", big.mark = ",")) +
  scale_fill_manual(
    values = colorRampPalette(c("#fee5c9", "#b5450a"))(10),
    guide  = "none"
  ) +
  labs(
    title    = "Ingreso corriente mensual promedio por decil de hogares",
    subtitle = "ENIGH 2024, pesos corrientes",
    x = "Decil", y = "Ingreso promedio mensual ($)",
    caption  = "Fuente: INEGI, ENIGH 2024."
  ) +
  theme_minimal(base_size = 12)

deciles_ingreso_plot

6.3 Desigualdad: razón 10/1 y participación en el ingreso

# Razón decil 10 / decil 1: ¿cuántas veces más gana el grupo más rico?
razon_10_1 <- ing_decil$ing_prom[ing_decil$decil_ingreso == 10] /
              ing_decil$ing_prom[ing_decil$decil_ingreso == 1]

cat("Razón decil 10 / decil 1:", round(razon_10_1, 1), "veces\n")
## Razón decil 10 / decil 1: 14.1 veces
# Participación porcentual de cada decil en el ingreso total
ing_decil <- ing_decil %>%
  mutate(participacion = ing_prom * n_hogares / sum(ing_prom * n_hogares) * 100)

print(select(ing_decil, decil_ingreso, ing_prom_mensual, participacion))
## # A tibble: 10 × 3
##    decil_ingreso ing_prom_mensual participacion
##            <dbl>            <dbl>         <dbl>
##  1             1            5598.          2.16
##  2             2            9432.          3.63
##  3             3           12281.          4.73
##  4             4           15081.          5.81
##  5             5           18102.          6.97
##  6             6           21533.          8.30
##  7             7           25816.          9.95
##  8             8           31763.         12.2 
##  9             9           41237.         15.9 
## 10            10           78697.         30.3
max_part <- max(ing_decil$participacion, na.rm = TRUE)

participacion_ingreso_plot <- ggplot(
  ing_decil,
  aes(x = factor(decil_ingreso), y = participacion, fill = factor(decil_ingreso))
) +
  geom_col(alpha = 0.85) +
  geom_text(
    aes(label = paste0(round(participacion, 0), "%")),
    vjust = -0.4, size = 3.5
  ) +
  scale_y_continuous(
    labels = function(x) paste0(x, "%"),
    limits = c(0, max_part * 1.1),
    expand = c(0, 0)
  ) +
  scale_fill_manual(
    values = colorRampPalette(c("#deebf7", "#08306b"))(10),
    guide  = "none"
  ) +
  labs(
    title    = "Participación de cada decil en el ingreso total",
    subtitle = "ENIGH 2024",
    x = "Decil de hogares", y = "Participación en el ingreso total (%)",
    caption  = "Fuente: INEGI, ENIGH 2024."
  ) +
  theme_minimal(base_size = 12) +
  theme(panel.grid.minor = element_blank())

participacion_ingreso_plot

6.4 Coeficiente de Gini

# El coeficiente de Gini mide desigualdad:
# 0 = igualdad perfecta (todos ganan lo mismo)
# 1 = desigualdad perfecta (un solo hogar concentra todo el ingreso)
# Para México, valores típicos están entre 0.40 y 0.55.

gini_val <- with(conc, gini(ing_cor, w = factor))
cat("Coeficiente de Gini (ENIGH 2024):", round(gini_val, 4), "\n")
## Coeficiente de Gini (ENIGH 2024): 0.4006

Interpretación: Un Gini cercano a 0.45 o superior indica una desigualdad elevada. México históricamente ha tenido un Gini alto en comparación con países desarrollados (que oscilan entre 0.25 y 0.35).


7 Pobreza por ingresos

Estimaremos la pobreza usando líneas de bienestar, que son el ingreso mínimo mensual per cápita necesario para satisfacer necesidades básicas. CONEVAL publica estas líneas oficialmente; en este laboratorio usamos valores ilustrativos.

7.1 Construcción del indicador de pobreza

# Paso 1: Calcular el ingreso mensual per cápita
conc <- conc %>%
  mutate(
    ing_mensual    = ing_cor / 3,
    ing_pc_mensual = ing_mensual / tot_integ  # per cápita = total / miembros
  )

# Paso 2: Clasificar zona urbana vs. rural
# tam_loc == 4 indica localidades rurales (menos de 2,500 habitantes)
conc <- conc %>%
  mutate(zona = if_else(tam_loc == 4, "Rural", "Urbano"))

# Paso 3: Definir líneas de bienestar (valores ilustrativos en MXN/mes/persona)
# Consulta las cifras oficiales actualizadas en: https://www.coneval.org.mx
lb_rural  <- 4200
lb_urbano <- 5800

# Paso 4: Clasificar hogares como pobres (1) o no pobres (0)
conc <- conc %>%
  mutate(
    linea_lb     = if_else(zona == "Rural", lb_rural, lb_urbano),
    pobre_ingreso = as.numeric(ing_pc_mensual < linea_lb)
  )

# Recreamos el diseño muestral con las nuevas variables
diseno3 <- conc %>%
  as_survey_design(ids = upm, strata = est_dis, weights = factor, nest = TRUE)

7.2 Tasa nacional de pobreza

tasa_pobreza <- diseno3 %>%
  summarise(
    tasa_pob     = survey_mean(pobre_ingreso, na.rm = TRUE, vartype = "ci"),
    total_pobres = survey_total(pobre_ingreso, na.rm = TRUE)
  )

cat("\n=== Pobreza por ingresos (nacional) ===\n")
## 
## === Pobreza por ingresos (nacional) ===
cat("Tasa de pobreza:", round(tasa_pobreza$tasa_pob * 100, 1), "%\n")
## Tasa de pobreza: 39.5 %
cat("Total de hogares en pobreza:",
    format(round(tasa_pobreza$total_pobres, 0), big.mark = ","), "\n")
## Total de hogares en pobreza: 15,337,476

8 Pobreza por entidad federativa

8.1 Creación de identificador de entidad y catálogo de nombres

# Los dos primeros dígitos de ubica_geo identifican la entidad federativa
conc <- conc %>%
  mutate(entidad = substr(ubica_geo, 1, 2))

# Catálogo de nombres de las 32 entidades federativas
cat_entidades <- tibble(
  entidad = sprintf("%02d", 1:32),
  nombre_entidad = c(
    "Aguascalientes", "Baja California", "Baja California Sur",
    "Campeche", "Coahuila", "Colima", "Chiapas", "Chihuahua",
    "Ciudad de México", "Durango", "Guanajuato", "Guerrero",
    "Hidalgo", "Jalisco", "Estado de México", "Michoacán",
    "Morelos", "Nayarit", "Nuevo León", "Oaxaca", "Puebla",
    "Querétaro", "Quintana Roo", "San Luis Potosí", "Sinaloa",
    "Sonora", "Tabasco", "Tamaulipas", "Tlaxcala", "Veracruz",
    "Yucatán", "Zacatecas"
  )
)

# Reconstruimos el diseño con la variable de entidad
diseno3 <- conc %>%
  as_survey_design(ids = upm, strata = est_dis, weights = factor, nest = TRUE)

8.2 Tasa de pobreza por estado

pob_entidad <- diseno3 %>%
  group_by(entidad) %>%
  summarise(tasa_pob = survey_mean(pobre_ingreso, na.rm = TRUE)) %>%
  left_join(cat_entidades, by = "entidad") %>%
  arrange(desc(tasa_pob))

pobreza_ingreso_estado <- ggplot(
  pob_entidad,
  aes(x = reorder(nombre_entidad, tasa_pob), y = tasa_pob, fill = nombre_entidad)
) +
  geom_col(alpha = 0.8) +
  geom_text(
    aes(label = paste0(round(tasa_pob * 100, 0), "%")),
    hjust = -0.1, size = 2.5
  ) +
  scale_y_continuous(labels = percent_format(accuracy = 1)) +
  scale_fill_viridis_d(option = "plasma", guide = "none") +
  coord_flip() +
  labs(
    title   = "Tasa de pobreza por ingresos según entidad federativa",
    x = "Entidad", y = "% hogares en pobreza",
    caption = "Fuente: INEGI, ENIGH 2024."
  ) +
  theme_minimal()

pobreza_ingreso_estado

8.3 Pobreza por entidad y zona (urbano/rural)

pob_entidad_zona <- diseno3 %>%
  group_by(entidad, zona) %>%
  summarise(tasa_pob = survey_mean(pobre_ingreso, na.rm = TRUE)) %>%
  left_join(cat_entidades, by = "entidad") %>%
  mutate(zona = factor(zona, levels = c("Urbano", "Rural")))

# --- Gráfica zona urbana ---
urban_data <- pob_entidad_zona %>% filter(zona == "Urbano")

urban_poverty_plot <- ggplot(
  urban_data,
  aes(x = fct_reorder(nombre_entidad, tasa_pob), y = tasa_pob, fill = nombre_entidad)
) +
  geom_col(alpha = 0.9) +
  geom_text(aes(label = paste0(round(tasa_pob * 100, 0), "%")), hjust = -0.1, size = 2.5) +
  scale_y_continuous(
    labels = percent_format(accuracy = 1),
    limits = c(0, max(urban_data$tasa_pob) * 1.05)
  ) +
  scale_fill_viridis_d(option = "viridis", guide = "none") +
  coord_flip() +
  labs(title = "Pobreza por ingresos – Zona Urbana", x = NULL, y = "% hogares en pobreza") +
  theme_minimal(base_size = 10) +
  theme(axis.text.y = element_text(size = 7))

urban_poverty_plot

# --- Gráfica zona rural ---
rural_data <- pob_entidad_zona %>% filter(zona == "Rural")

rural_poverty_plot <- ggplot(
  rural_data,
  aes(x = fct_reorder(nombre_entidad, tasa_pob), y = tasa_pob, fill = nombre_entidad)
) +
  geom_col(alpha = 0.9) +
  geom_text(aes(label = paste0(round(tasa_pob * 100, 0), "%")), hjust = -0.1, size = 2.5) +
  scale_y_continuous(
    labels = percent_format(accuracy = 1),
    limits = c(0, max(rural_data$tasa_pob) * 1.05)
  ) +
  scale_fill_viridis_d(option = "viridis", guide = "none") +
  coord_flip() +
  labs(title = "Pobreza por ingresos – Zona Rural", x = NULL, y = "% hogares en pobreza") +
  theme_minimal(base_size = 10) +
  theme(axis.text.y = element_text(size = 7))

rural_poverty_plot

Pregunta de reflexión: ¿Qué entidades muestran la mayor brecha entre pobreza urbana y rural? ¿A qué factores estructurales podría atribuirse esa diferencia?


9 Análisis del gasto de los hogares

9.1 Construcción de variables de gasto

# Convertimos todos los rubros de gasto de trimestral a mensual.
# Dividir entre 3 porque la ENIGH captura el gasto del trimestre de referencia.
conc <- conc %>%
  mutate(
    gasto_mensual  = gasto_mon / 3,
    gasto_pc       = gasto_mensual / tot_integ,       # per cápita
    g_alimentos    = (ali_dentro + ali_fuera) / 3,    # alimentos en casa + fuera
    g_vivienda     = vivienda / 3,
    g_transporte   = transporte / 3,
    g_salud        = salud / 3,
    g_educacion    = educacion / 3,
    g_vestido      = vesti_calz / 3,
    g_comunicacion = comunica / 3,
    g_otros        = otros_gas / 3
  )

9.2 Deciles de gasto per cápita

# Construimos deciles de gasto per cápita con el método acumulativo
conc <- conc %>%
  arrange(gasto_pc) %>%
  mutate(
    acum_peso_gasto  = cumsum(factor),
    total_peso_gasto = sum(factor),
    decil_gasto      = ceiling(acum_peso_gasto / total_peso_gasto * 10),
    decil_gasto      = pmin(decil_gasto, 10)
  )

# Reconstruimos el diseño
diseno3 <- conc %>%
  as_survey_design(ids = upm, strata = est_dis, weights = factor, nest = TRUE)

# Gasto e ingreso promedio mensual por decil de gasto
gasto_decil <- diseno3 %>%
  group_by(decil_gasto) %>%
  summarise(
    gasto_med   = survey_mean(gasto_mensual, na.rm = TRUE),
    ingreso_med = survey_mean(ing_mensual, na.rm = TRUE)
  ) %>%
  mutate(decil_gasto = factor(decil_gasto))
max_gasto <- max(gasto_decil$gasto_med, na.rm = TRUE)

gasto_deciles_plot <- ggplot(
  gasto_decil,
  aes(x = factor(decil_gasto), y = gasto_med, fill = factor(decil_gasto))
) +
  geom_col(alpha = 0.85) +
  geom_text(
    aes(label = paste0("$", format(round(gasto_med, 0), big.mark = ","))),
    vjust = -0.4, size = 3
  ) +
  scale_y_continuous(
    labels = dollar_format(prefix = "$"),
    limits = c(0, max_gasto * 1.15),
    expand = expansion(mult = c(0, 0))
  ) +
  scale_fill_manual(
    values = colorRampPalette(c("#deebf7", "#08306b"))(10),
    guide  = "none"
  ) +
  labs(
    title = "Gasto mensual promedio del hogar por decil de gasto per cápita",
    x = "Decil de gasto per cápita", y = "Gasto mensual ($MXN)"
  ) +
  theme_minimal()

gasto_deciles_plot

9.3 Propensión marginal al consumo (PMC)

La propensión marginal al consumo indica qué fracción del ingreso se destina al gasto. Si es mayor a 1, el hogar está gastando más de lo que gana (desahorro o deuda).

apc_df <- data.frame(
  decil            = 1:10,
  gasto_med        = gasto_decil$gasto_med,
  ing_prom_mensual = ing_decil$ing_prom_mensual,
  apc              = gasto_decil$gasto_med / ing_decil$ing_prom_mensual
)

apc_plot <- ggplot(apc_df, aes(x = factor(decil), y = apc, fill = factor(decil))) +
  geom_col(alpha = 0.85) +
  geom_text(aes(label = paste0(round(apc * 100, 1), "%")), vjust = -0.3, size = 3.5) +
  scale_y_continuous(
    labels = percent_format(accuracy = 1),
    limits = c(0, max(apc_df$apc) * 1.1)
  ) +
  scale_fill_manual(
    values = colorRampPalette(c("#00441b", "#e5f5e0"))(10),
    guide  = "none"
  ) +
  labs(
    title    = "Propensión marginal al consumo por decil",
    subtitle = "Gasto mensual del hogar / Ingreso mensual del hogar",
    x = "Decil", y = "Proporción (gasto / ingreso)"
  ) +
  theme_minimal()

apc_plot

¿Qué esperarías ver? Los hogares del decil 1 (más pobres) típicamente gastan más de lo que declaran ganar, reflejando limitaciones en la medición del ingreso informal o endeudamiento. Los hogares del decil 10 ahorran una proporción considerable de su ingreso.

9.4 Composición del gasto por decil

categorias <- c("g_alimentos", "g_vivienda", "g_transporte", "g_salud",
                "g_educacion", "g_vestido", "g_comunicacion", "g_otros")

# Gasto promedio por categoría y decil (ponderado)
gasto_final <- diseno3 %>%
  group_by(decil_gasto) %>%
  summarise(
    across(all_of(categorias), ~ survey_mean(.x, na.rm = TRUE), .names = "{.col}")
  ) %>%
  select(decil_gasto, all_of(categorias)) %>%
  pivot_longer(-decil_gasto, names_to = "categoria", values_to = "gasto") %>%
  mutate(
    categoria = recode(
      categoria,
      g_alimentos    = "Alimentos",   g_vivienda    = "Vivienda",
      g_transporte   = "Transporte",  g_salud       = "Salud",
      g_educacion    = "Educación",   g_vestido     = "Vestido",
      g_comunicacion = "Comunicación", g_otros      = "Otros"
    )
  ) %>%
  group_by(decil_gasto, categoria) %>%
  summarise(gasto = sum(gasto), .groups = "drop") %>%
  group_by(decil_gasto) %>%
  arrange(decil_gasto, desc(gasto)) %>%
  mutate(
    total_decil = sum(gasto),
    pct         = gasto / total_decil,
    pos         = cumsum(gasto) - (gasto / 2)
  ) %>%
  ungroup()

descomposicion_gasto_decil <- ggplot(gasto_final, aes(x = factor(decil_gasto), y = gasto)) +
  geom_col(
    aes(fill = fct_reorder(categoria, gasto)),
    position = "stack", alpha = 0.9, color = "white", linewidth = 0.1
  ) +
  geom_text(
    aes(y = pos, label = ifelse(pct >= 0.05, paste0(round(pct * 100, 0), "%"), "")),
    size = 3, color = "white", fontface = "bold"
  ) +
  geom_text(
    data = distinct(gasto_final, decil_gasto, total_decil),
    aes(x = factor(decil_gasto), y = total_decil,
        label = paste0("$", format(round(total_decil, 0), big.mark = ","))),
    inherit.aes = FALSE, vjust = -0.5, size = 3, color = "gray20"
  ) +
  scale_fill_brewer(palette = "Set2") +
  scale_y_continuous(
    breaks = seq(0, 30000, by = 3000),
    labels = dollar_format(prefix = "$"),
    expand = expansion(mult = c(0, 0.15))
  ) +
  labs(
    title = "Composición del gasto mensual del hogar por decil",
    x = "Decil de gasto per cápita", y = "Pesos MXN", fill = "Rubro"
  ) +
  theme_minimal() +
  theme(legend.position = "bottom")

descomposicion_gasto_decil

Ley de Engel: En economía, se observa que los hogares con menor ingreso destinan una mayor proporción de su gasto a alimentos. ¿Se cumple esta ley en los datos de la ENIGH?


10 Análisis exploratorio de predictores de pobreza

Antes de construir modelos, exploramos visualmente cómo se relacionan distintas variables con la condición de pobreza.

10.1 Construcción de variables predictoras

conc <- conc %>%
  mutate(
    # Variable binaria de zona rural
    rural = as.numeric(zona == "Rural"),

    # Logaritmo del tamaño del hogar (reduce el efecto de valores extremos)
    log_tam_hogar = log(tot_integ),

    # Educación del jefe/jefa de hogar normalizada a escala 0-1
    edu_numeric = case_when(
      educa_jefe %in% c("Sin instrucción", "Preescolar") ~ 0,
      educa_jefe == "Primaria"      ~ 1,
      educa_jefe == "Secundaria"    ~ 2,
      educa_jefe == "Preparatoria"  ~ 3,
      educa_jefe == "Profesional"   ~ 4,
      educa_jefe == "Posgrado"      ~ 5,
      TRUE ~ NA_real_
    ),
    edu_jefe = if_else(is.na(edu_numeric), 0.3, edu_numeric / 5),

    # Ratio: perceptores de ingreso / total de miembros del hogar
    ratio_percep = if_else(tot_integ > 0, percep_ing / tot_integ, 0),

    entidad = substr(ubica_geo, 1, 2)
  ) %>%
  select(-edu_numeric)

10.2 Pobreza por zona

cat("\n=== Tasa de pobreza por zona ===\n")
## 
## === Tasa de pobreza por zona ===
conc %>%
  group_by(zona) %>%
  summarise(
    tasa_pobreza = weighted.mean(pobre_ingreso, factor, na.rm = TRUE),
    n_hogares    = n()
  ) %>%
  print()
## # A tibble: 2 × 3
##   zona   tasa_pobreza n_hogares
##   <chr>         <dbl>     <int>
## 1 Rural         0.533     35825
## 2 Urbano        0.359     55589

10.3 Pobreza por nivel educativo del jefe/jefa de hogar

# Clasificación en quintiles de educación para análisis comparativo
conc <- conc %>%
  mutate(quintil_edu = factor(ntile(edu_jefe, 5), labels = paste0("Q", 1:5)))

cat("\nPobreza por quintil de educación del jefe/jefa:\n")
## 
## Pobreza por quintil de educación del jefe/jefa:
conc %>%
  group_by(quintil_edu) %>%
  summarise(
    tasa_pobreza = weighted.mean(pobre_ingreso, factor, na.rm = TRUE),
    edu_promedio = weighted.mean(edu_jefe * 11, factor, na.rm = TRUE),
    .groups = "drop"
  ) %>%
  print()
## # A tibble: 5 × 3
##   quintil_edu tasa_pobreza edu_promedio
##   <fct>              <dbl>        <dbl>
## 1 Q1                0.824           3.3
## 2 Q2                0.654           3.3
## 3 Q3                0.439           3.3
## 4 Q4                0.191           3.3
## 5 Q5                0.0350          3.3

10.4 Gráficas de predictores

10.4.1 Educación y pobreza

# Funciones auxiliares para aclarar/oscurecer colores base
lighten <- function(color, factor = 0.6) {
  rgb_vals <- col2rgb(color) / 255
  rgb_vals <- rgb_vals + (1 - rgb_vals) * (1 - factor)
  rgb(rgb_vals[1], rgb_vals[2], rgb_vals[3])
}
darken <- function(color, factor = 0.6) {
  rgb_vals <- col2rgb(color) / 255
  rgb_vals <- rgb_vals * factor
  rgb(rgb_vals[1], rgb_vals[2], rgb_vals[3])
}

# Categorías de educación a partir de los códigos de la ENIGH
conc <- conc %>%
  mutate(
    edu_cat = case_when(
      educa_jefe == "01" ~ "Sin instrucción",
      educa_jefe == "02" ~ "Preescolar",
      educa_jefe == "03" ~ "Primaria",
      educa_jefe == "04" ~ "Secundaria",
      educa_jefe == "05" ~ "Preparatoria",
      educa_jefe == "06" ~ "Profesional",
      educa_jefe == "07" ~ "Posgrado",
      educa_jefe %in% c("08", "09", "10", "11") ~ "Técnico / Normal",
      TRUE ~ NA_character_
    )
  )

edu_levels <- c("Sin instrucción", "Preescolar", "Primaria", "Secundaria",
                "Preparatoria", "Técnico / Normal", "Profesional", "Posgrado")
conc$edu_cat <- factor(conc$edu_cat, levels = edu_levels)

conc <- conc %>%
  mutate(pobreza_label = ifelse(pobre_ingreso == 1, "Pobre", "No pobre"))

# Conteos ponderados por grupo educación × pobreza
plot_data <- conc %>%
  filter(!is.na(edu_cat), !is.na(pobreza_label), !is.na(factor)) %>%
  group_by(edu_cat, pobreza_label) %>%
  summarise(weighted_n = sum(factor), .groups = "drop")

base_colors <- c("#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd",
                 "#8c564b", "#e377c2", "#7f7f7f")
names(base_colors) <- edu_levels

plot_data <- plot_data %>%
  rowwise() %>%
  mutate(
    fill_color = ifelse(
      pobreza_label == "No pobre",
      lighten(base_colors[as.character(edu_cat)], 0.7),
      darken(base_colors[as.character(edu_cat)], 0.7)
    )
  ) %>%
  ungroup()

plot_data <- plot_data %>%
  mutate(combo = paste(edu_cat, pobreza_label, sep = ": "))
combo_order <- c()
for (lvl in edu_levels) {
  combo_order <- c(combo_order,
                   paste(lvl, "No pobre", sep = ": "),
                   paste(lvl, "Pobre",    sep = ": "))
}
plot_data$combo <- factor(plot_data$combo, levels = combo_order)
plot_data <- plot_data %>%
  mutate(label = paste0(round(weighted_n / 1e6, 1), "M"))

p_edu_correct <- ggplot(
  plot_data,
  aes(x = edu_cat, y = weighted_n, fill = combo, label = label)
) +
  geom_col(position = position_dodge(width = 0.9), alpha = 0.9) +
  geom_text(
    position = position_dodge(width = 0.9),
    aes(y = weighted_n + 0.02 * max(weighted_n)),
    vjust = 0, size = 3
  ) +
  scale_fill_manual(
    values = setNames(plot_data$fill_color, plot_data$combo),
    name   = "Condición"
  ) +
  scale_y_continuous(labels = label_number(scale = 1e-6, suffix = "M")) +
  labs(
    title = "Nivel educativo del jefe/jefa de hogar según condición de pobreza",
    x = "Nivel educativo", y = "Número de hogares (millones)"
  ) +
  theme_minimal(base_size = 12) +
  theme(legend.position = "right", axis.text.x = element_text(angle = 45, hjust = 1))

p_edu_correct

10.4.2 Perceptores de ingreso y pobreza

p_percep <- ggplot(
  conc %>%
    filter(!is.na(ratio_percep)) %>%
    mutate(condicion = factor(pobre_ingreso, labels = c("No pobre", "Pobre"))),
  aes(x = condicion, y = ratio_percep, fill = condicion)
) +
  geom_violin(alpha = 0.6, trim = TRUE) +
  geom_boxplot(width = 0.15, outlier.shape = NA, fill = "white", alpha = 0.8) +
  scale_fill_manual(
    values = c("No pobre" = "#2166ac", "Pobre" = "#b5450a"),
    guide  = "none"
  ) +
  labs(
    title    = "Ratio perceptores/miembros por condición de pobreza",
    subtitle = "Los hogares pobres tienen menor diversificación de ingresos",
    x = NULL, y = "Perceptores de ingreso / total de miembros",
    caption  = "Fuente: INEGI, ENIGH 2024."
  ) +
  theme_minimal(base_size = 12)

p_percep

10.4.3 Tamaño del hogar y pobreza

p_tam <- conc %>%
  mutate(
    tam_cat = cut(tot_integ,
                  breaks = c(0, 2, 4, 6, Inf),
                  labels = c("1-2", "3-4", "5-6", "7+"))
  ) %>%
  group_by(tam_cat) %>%
  summarise(
    tasa_pob  = weighted.mean(pobre_ingreso, factor, na.rm = TRUE),
    n_hogares = n()
  ) %>%
  ggplot(aes(x = tam_cat, y = tasa_pob, fill = tam_cat)) +
  geom_col(alpha = 0.85) +
  geom_text(
    aes(label = percent(tasa_pob, accuracy = 0.1)),
    vjust = -0.4, size = 4
  ) +
  scale_y_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.12))
  ) +
  scale_fill_manual(
    values = c("1-2" = "#deebf7", "3-4" = "#9ecae1",
               "5-6" = "#3182bd", "7+"  = "#08306b"),
    guide  = "none"
  ) +
  labs(
    title    = "Tasa de pobreza según tamaño del hogar",
    subtitle = "Los hogares numerosos tienen mayor riesgo de pobreza",
    x = "Número de miembros", y = "Tasa de pobreza",
    caption  = "Fuente: INEGI, ENIGH 2024."
  ) +
  theme_minimal(base_size = 12)

p_tam


11 Introducción a la inferencia bayesiana aplicada a la pobreza

Hasta ahora hemos usado estadística frecuentista (medias ponderadas, intervalos de confianza). En esta sección introducimos el enfoque bayesiano, que combina la información de los datos con conocimiento previo (prior).

11.1 ¿Qué es la inferencia bayesiana?

En términos simples:

  • Prior (\(\alpha\), \(\beta\)): lo que sabemos o creemos antes de ver los datos.
  • Verosimilitud: información que aportan los datos observados.
  • Posterior: nuestra creencia actualizada después de combinar ambos.

Para una proporción (como la tasa de pobreza \(\theta\)), el modelo conjugado es:

\[\theta \sim \text{Beta}(\alpha, \beta) \quad \text{(prior)}\] \[\text{Posterior}: \theta | \text{datos} \sim \text{Beta}(\alpha + \text{pobres}, \; \beta + \text{no pobres})\]

11.2 Comparación de distribuciones posteriores con muestra pequeña

Con muestras pequeñas, la elección del prior importa mucho. Con muestras grandes, los datos dominan.

set.seed(123)

# Tomamos una submuestra pequeña de 30 hogares para que el prior tenga efecto visible
tiny_sample <- conc %>% sample_n(30)
n_pobres_tiny <- sum(tiny_sample$pobre_ingreso, na.rm = TRUE)
n_total_tiny  <- nrow(tiny_sample)

cat("Muestra pequeña: n =", n_total_tiny,
    ", pobres =", n_pobres_tiny,
    ", tasa =", round(n_pobres_tiny / n_total_tiny * 100, 1), "%\n")
## Muestra pequeña: n = 30 , pobres = 10 , tasa = 33.3 %
# Definimos cinco priors con diferentes supuestos iniciales
priors <- list(
  "Uniforme (Beta 1,1)"      = c(1, 1),   # sin información previa
  "Débil (Beta 2,2)"         = c(2, 2),   # leve preferencia por 50%
  "Fuerte 50% (Beta 50,50)"  = c(50, 50), # convicción fuerte de que θ ≈ 0.5
  "Escéptico (Beta 5,15)"    = c(5, 15),  # cree que la tasa es baja (~25%)
  "Optimista (Beta 15,5)"    = c(15, 5)   # cree que la tasa es alta (~75%)
)

theta_grid   <- seq(0, 1, length.out = 500)
df_posteriors <- tibble()

for (prior_name in names(priors)) {
  a_prior <- priors[[prior_name]][1]
  b_prior <- priors[[prior_name]][2]

  # Parámetros de la distribución posterior
  a_post <- a_prior + n_pobres_tiny
  b_post <- b_prior + (n_total_tiny - n_pobres_tiny)

  dens <- dbeta(theta_grid, a_post, b_post)

  df_posteriors <- bind_rows(df_posteriors,
                             tibble(theta = theta_grid, densidad = dens, prior = prior_name))
}

# Ordenamos los factores para la leyenda
df_posteriors$prior <- factor(df_posteriors$prior, levels = c(
  "Uniforme (Beta 1,1)", "Débil (Beta 2,2)", "Escéptico (Beta 5,15)",
  "Optimista (Beta 15,5)", "Fuerte 50% (Beta 50,50)"
))

colores_priors <- c(
  "Uniforme (Beta 1,1)"     = "gray50",
  "Débil (Beta 2,2)"        = "#1f77b4",
  "Escéptico (Beta 5,15)"   = "#2ca02c",
  "Optimista (Beta 15,5)"   = "#d62728",
  "Fuerte 50% (Beta 50,50)" = "#9467bd"
)

p_alpha <- ggplot(df_posteriors, aes(x = theta, y = densidad, fill = prior)) +
  geom_area(alpha = 0.4, position = "identity") +
  scale_x_continuous(labels = percent_format(accuracy = 1), limits = c(0, 1)) +
  scale_fill_manual(values = colores_priors) +
  labs(
    title    = paste("Distribuciones posteriores con muestra pequeña (n =", n_total_tiny, ")"),
    subtitle = paste("Hogares pobres en la muestra:", n_pobres_tiny, "/", n_total_tiny,
                     "(", round(n_pobres_tiny / n_total_tiny * 100, 1), "%)"),
    x = "Tasa de pobreza (θ)", y = "Densidad posterior",
    fill = "Prior"
  ) +
  theme_minimal(base_size = 12) +
  theme(legend.position = "bottom")

p_alpha

Observa: Con solo 30 hogares, los distintos priors producen distribuciones posteriores notablemente diferentes. Un prior “fuerte” que asume 50% de pobreza jala la posterior hacia ese valor, mientras que el prior uniforme deja que los datos hablen solos.

11.3 Sensibilidad a la línea de bienestar

¿Qué tan sensibles son nuestras estimaciones de pobreza al valor exacto de la línea de bienestar? Esta es una pregunta crucial de política pública.

set.seed(123)
n_muestra <- 200
submuestra <- conc %>% sample_n(n_muestra)

lb_rural_base  <- 4200
lb_urbano_base <- 5800

# Ajustes del -15% al +15% de la línea de bienestar
ajustes        <- c(-0.15, -0.10, -0.05, 0, 0.05, 0.10, 0.15)
ajustes_labels <- paste0(ajustes * 100, "%")

priors <- list(
  "Uniforme (Beta 1,1)"     = c(1, 1),
  "Débil (Beta 2,2)"        = c(2, 2),
  "Escéptico (Beta 5,15)"   = c(5, 15),
  "Optimista (Beta 15,5)"   = c(15, 5),
  "Fuerte 50% (Beta 50,50)" = c(50, 50)
)

df_curvas <- tibble()

for (prior_nombre in names(priors)) {
  a_prior <- priors[[prior_nombre]][1]
  b_prior <- priors[[prior_nombre]][2]

  for (z in c("Rural", "Urbano")) {
    data_z    <- submuestra %>% filter(zona == z)
    n_total_z <- nrow(data_z)
    if (n_total_z == 0) next

    for (adj in ajustes) {
      lb_base   <- ifelse(z == "Rural", lb_rural_base, lb_urbano_base)
      lb_adj    <- lb_base * (1 + adj)
      n_pobres_z <- sum(data_z$ing_pc_mensual < lb_adj, na.rm = TRUE)

      a_post    <- a_prior + n_pobres_z
      b_post    <- b_prior + (n_total_z - n_pobres_z)

      theta_grid <- seq(0, 1, length.out = 500)
      densidad   <- dbeta(theta_grid, a_post, b_post)

      df_curvas <- bind_rows(df_curvas,
                             tibble(
                               theta        = theta_grid,
                               densidad     = densidad,
                               prior        = prior_nombre,
                               zona         = z,
                               ajuste_label = paste0(round(adj * 100), "%")
                             ))
    }
  }
}

df_curvas$ajuste_label <- factor(df_curvas$ajuste_label, levels = ajustes_labels)

p_todos_priors <- ggplot(df_curvas, aes(x = theta, y = densidad, fill = ajuste_label)) +
  geom_area(alpha = 0.4, position = "identity") +
  scale_x_continuous(labels = percent_format(accuracy = 1), limits = c(0, 1)) +
  scale_fill_brewer(palette = "RdYlBu", direction = -1, name = "Ajuste de línea") +
  facet_grid(prior ~ zona, scales = "free_y") +
  labs(
    title    = paste("Sensibilidad a la línea de bienestar para diferentes priors",
                     "(submuestra de", n_muestra, "hogares)"),
    subtitle = "Cada panel muestra la distribución posterior de la tasa de pobreza según el ajuste de línea",
    x = "Tasa de pobreza (θ)", y = "Densidad posterior"
  ) +
  theme_minimal(base_size = 10) +
  theme(
    legend.position = "bottom",
    strip.text      = element_text(face = "bold"),
    axis.text.x     = element_text(angle = 45, hjust = 1)
  )

p_todos_priors

Lección clave: La tasa de pobreza es muy sensible a dónde trazamos la línea de bienestar. Un ajuste del 10% puede cambiar significativamente cuántos hogares clasificamos como pobres, especialmente en zonas rurales. Por eso las decisiones metodológicas de CONEVAL sobre las líneas de bienestar tienen un enorme impacto en las estadísticas oficiales.


12 Reflexiones finales del laboratorio

Este laboratorio cubre un recorrido completo desde la carga de datos hasta la inferencia bayesiana. Algunos puntos clave para recordar:

Sobre el diseño muestral: La ENIGH no es una muestra aleatoria simple. Siempre debes declarar el diseño con as_survey_design() y usar funciones survey_* para obtener estimaciones válidas.

Sobre la desigualdad: La razón 10/1 y el coeficiente de Gini muestran el nivel de desigualdad del ingreso. Compara los resultados con ediciones anteriores de la ENIGH para ver la evolución histórica.

Sobre las líneas de pobreza: Las líneas usadas en este laboratorio son ilustrativas. Para análisis oficiales, consulta siempre las cifras publicadas por CONEVAL, que actualizan mensualmente las líneas de bienestar.

Sobre la inferencia bayesiana: Con muestras grandes como la ENIGH completa, los priors tienen poca influencia. Su efecto es más visible con submuestras pequeñas. El enfoque bayesiano es especialmente útil para estimaciones en grupos pequeños (municipios, grupos de edad) donde los datos son escasos.