Cómo leer (y no malinterpretar) la ENAHO
Una guía práctica de los conceptos que separan una tabla correcta de una equivocada al trabajar con microdatos del INEI: diseño muestral, factores de expansión, varianza, escalera de conceptos laborales y plantillas de código.
1. Diseño muestral en dos etapas
La ENAHO es probabilística, estratificada, multietápica e independiente por departamento. En el área urbana la primera etapa selecciona conglomerados (manzanas agrupadas, ~140 viviendas) y la segunda viviendas; en el área rural, centros poblados/áreas de empadronamiento rural y luego viviendas. Los estratos combinan departamento y tamaño del centro poblado (estrato 1–5 urbano, 6–8 rural). Consecuencia: dos personas del mismo conglomerado no son observaciones independientes.
2. Factores de expansión
Cada módulo trae su factor. Para el módulo 500 se usa fac500a; para el 200, facpob07; para hogar (sumaria), factor07. Usar el factor de otro módulo sesga los totales. La suma de fac500a sobre personas 14+ reproduce la PET (26,8 millones en 2024).
3. Varianza con diseño complejo
El error estándar "ingenuo" (como si la muestra fuera aleatoria simple) subestima la incertidumbre. La linealización de Taylor agrega las contribuciones por conglomerado dentro de cada estrato:
Var(R̂) = Σ_h n_h/(n_h−1) Σ_c ( Z_hc − Z̄_h )², con z_i = w_i (y_i − R̂ x_i) / X̂
Para medianas, el intervalo de Woodruff invierte la función de distribución ponderada alrededor del cuantil. Un RSE (se/estimación) mayor a 15 % debe hacer dudar de la cifra; mayor a 30 %, no publicarla.
4. Escalera de conceptos
| Concepto | Variable | Cuidado con |
|---|---|---|
| PET | edad ≥ 14 (p208a) | No usar 15+ (convención OIT) si se compara con INEI. |
| PEA / ocupado / desocupado | ocu500 = 1, 2 (3 = desocupado oculto, 4 = inactivo) | Incluir el código 3 sube la tasa de desempleo ~1,7 pp. |
| Categoría ocupacional | p507 | Sólo ocupados; NA en el resto. |
| Informalidad | ocupinf (2014–2023) | NA para no ocupados: nunca convertir a 0. Ausente en 2024. |
| Horas | p513t, p518, p519, i520 | i520 sólo está lleno cuando la semana pasada no fue normal. |
| Ingreso laboral | i524a1, i530a, i538a1, i541a | Son anuales e imputados; dividir entre 12; deflactar. |
| Educación | p301a (módulo 300) | p212 no es nivel educativo. |
| Seguro de salud | p4191–p4198 (módulo 400) | p558a* es pensiones, no salud. |
| Llaves de unión | conglome, vivienda, hogar, codperso | Ceros a la izquierda: en .sav son texto, en .dta a veces numéricos. |
5. Plantillas
Python (pandas + pyreadstat)
import pyreadstat, pandas as pd
df, meta = pyreadstat.read_dta("enaho01a-2023-500.dta", usecols=["conglome","vivienda","hogar","codperso","ocu500","p207","p208a","fac500a","ocupinf"])
df.columns = df.columns.str.lower()
pet = df[df.p208a >= 14]
pea = pet[pet.ocu500.isin([1, 2])]
tasa_actividad = pea.fac500a.sum() / pet.fac500a.sum()
desempleo = pea.loc[pea.ocu500 == 2, "fac500a"].sum() / pea.fac500a.sum() R (survey)
library(haven); library(survey); library(dplyr)
d <- read_dta("enaho01a-2023-500.dta") |> rename_all(tolower) |> filter(p208a >= 14)
options(survey.lonely.psu = "adjust")
des <- svydesign(ids = ~conglome, strata = ~interaction(substr(ubigeo,1,2), estrato), weights = ~fac500a, data = d, nest = TRUE)
svymean(~I(ocu500 %in% 1:2), des) # tasa de actividad
svyby(~I(ocu500 == 2), ~p207, subset(des, ocu500 %in% 1:2), svymean) # desempleo por sexo Stata
use enaho01a-2023-500.dta, clear keep if p208a >= 14 gen dept = substr(ubigeo, 1, 2) egen strat = group(dept estrato) svyset conglome [pw = fac500a], strata(strat) singleunit(centered) gen pea = inlist(ocu500, 1, 2) gen desocupado = ocu500 == 2 if pea svy: mean pea svy: mean desocupado, over(p207)
El pipeline completo del Observatorio (Python) reproduce estas operaciones para 2014–2024 y publica cada resultado con su error estándar. Ver Metodología.