ENAHO 2022 · R · svySE

Indicadores sociales y errores muestrales en un flujo reproducible

Este artículo muestra cómo construir indicadores seleccionados de la ENAHO 2022 en R y cómo estimar sus medidas de precisión con svySE, manteniendo un flujo claro, auditable y orientado a reportes técnicos.

Diseño complejo Taylor linearization IC 95% CV y DEFF Exportación Excel

1

Construcción

Se definen indicadores binarios a partir de los módulos de salud, educación, vivienda, energía y conectividad.

2

Estimación

Se consideran ponderadores, estratos y conglomerados para obtener estimaciones y errores muestrales.

3

Salida

Se exportan tablas completas o personalizadas para revisión, anexos técnicos o reportes institucionales.

Cómo leer este documento. El índice lateral permite avanzar por dimensiones e indicadores. Los bloques de código pueden mostrarse u ocultarse con el botón Code, de modo que el documento funcione tanto como explicación metodológica como guía reproducible.

1 Presentación

Este documento muestra una forma práctica de construir un conjunto de indicadores de la Encuesta Nacional de Hogares 2022 (ENAHO) en R y, a partir de ellos, calcular sus errores muestrales usando el paquete svySE.

La idea no es proponer una única forma de trabajo ni comparar herramientas. En el análisis estadístico aplicado existen distintos flujos posibles, y cada equipo elige el que mejor se ajusta a sus procesos. Este ejemplo busca mostrar que también es posible trabajar estos indicadores en R de manera ordenada, reproducible y cercana al flujo operativo que se usa cuando se producen tablas de indicadores con estimaciones, porcentajes, errores estándar, intervalos de confianza, coeficientes de variación, efectos de diseño y recuentos no ponderados.

Como referencia metodológica se toma la ficha técnica oficial de indicadores generados a partir de la ENAHO, publicada por el INEI:

https://proyectos.inei.gob.pe/iinei/srienaho/Descarga/FichaTecnica/854-1788-Ficha.pdf

En esa ficha se presentan indicadores de salud, educación, vivienda y entorno, energía y conectividad, junto con su población objetivo, fórmula general, criterios de construcción y sintaxis de referencia. En este artículo se usa esa lógica como punto de partida para construir variables binarias en R y luego pasarlas a svySE.

2 ¿Por qué usar svySE?

Cuando se trabaja con encuestas complejas, no basta con calcular porcentajes simples. La ENAHO cuenta con ponderadores, estratos y conglomerados. Por ello, las estimaciones deben considerar el diseño muestral. En la práctica, esto significa que, además del valor estimado del indicador, es recomendable reportar medidas de precisión como:

  • error estándar;
  • intervalo de confianza al 95%;
  • coeficiente de variación;
  • efecto del diseño;
  • recuento no ponderado.
Estimación
Total y %
Precisión
SE e IC95%
Calidad
CV
Diseño
DEFF

El paquete svySE fue desarrollado para simplificar ese proceso. Su objetivo es que el usuario pueda concentrarse en dos momentos clave: primero, construir correctamente los indicadores; segundo, calcular los errores muestrales de forma estandarizada.

3 Base técnica del flujo de trabajo

svySE no parte desde cero. El paquete organiza un flujo de trabajo práctico alrededor de herramientas ampliamente utilizadas en R para el análisis de encuestas complejas, el manejo de bases de datos y la exportación de resultados.

La estimación de los errores muestrales se apoya principalmente en el paquete survey, que es una de las librerías más importantes en R para trabajar con diseños muestrales complejos. A través de esta base se construyen diseños con estratos, conglomerados y factores de expansión, y se calculan estimaciones, errores estándar, intervalos de confianza, coeficientes de variación y efectos del diseño.

En este artículo, además, se utiliza haven para leer bases de datos en formato .sav, formato en el que se encuentran los módulos de trabajo de la ENAHO 2022 usados en el ejemplo. Para la preparación de variables, unión de módulos y ordenamiento del flujo de datos se utilizan funciones de apoyo de R y, cuando resulta conveniente, del ecosistema tidyverse.

La exportación de resultados se realiza mediante openxlsx, lo que permite generar archivos Excel con tablas de errores muestrales y tablas simples, manteniendo la posibilidad de personalizar columnas, hojas, filas iniciales y estructura de salida.

En ese sentido, svySE busca facilitar un proceso que normalmente requiere varios pasos separados: preparar indicadores, definir el diseño muestral, calcular medidas de precisión y exportar los resultados en un formato útil para revisión técnica o elaboración de reportes.

3.1 Librerías utilizadas

Librería Uso dentro del flujo
svySE Organiza el cálculo de indicadores, errores muestrales, tablas simples y exportación a Excel.
survey Base metodológica para diseños muestrales complejos, estimaciones ponderadas, errores estándar, CV, DEFF e intervalos de confianza.
openxlsx Generación de archivos Excel personalizados con resultados de errores muestrales y tablas simples.
haven Lectura de bases ENAHO en formato .sav.
dplyr Preparación, transformación y unión de bases de datos.
knitr Presentación de tablas dentro del documento R Markdown.

Es importante distinguir entre las librerías que forman parte del funcionamiento interno de svySE y las librerías usadas en este artículo. svySE se apoya principalmente en survey, openxlsx y funciones base de R; mientras que haven, dplyr y knitr se utilizan aquí para leer los archivos .sav, preparar la base de trabajo y presentar los resultados en el documento.

4 Instalación de paquetes

La versión de desarrollo de svySE puede instalarse desde GitHub:

install.packages("remotes")
remotes::install_github("lburgoss/svySE")

Para este ejemplo se usarán los siguientes paquetes:

library(haven)
library(dplyr)
library(stringr)
library(svySE)

Si se desea citar el paquete dentro de un trabajo o reporte, puede usarse:

citation("svySE")

5 Archivos de trabajo

El ejemplo asume que los módulos de ENAHO 2022 se encuentran en formato .sav en una carpeta local. La estructura puede adaptarse a la ubicación real de los archivos en cada computadora.

Los nombres usados en este documento son:

ruta_enaho <- "C:/Users/encal154/Desktop/Versiones svySE/RPUB/ENAHO_2022"

file_100 <- file.path(ruta_enaho, "Enaho01-2022-100.sav")
file_200 <- file.path(ruta_enaho, "Enaho01-2022-200.sav")
file_300 <- file.path(ruta_enaho, "Enaho01A-2022-300.sav")
file_400 <- file.path(ruta_enaho, "Enaho01A-2022-400.sav")

Los módulos usados son:

Módulo Archivo Uso principal en este ejemplo
100 Enaho01-2022-100.sav Características de la vivienda y del hogar
200 Enaho01-2022-200.sav Características de los miembros del hogar
300 Enaho01-2022-300.sav Educación y acceso a internet
400 Enaho01-2022-400.sav Salud

Una recomendación práctica es convertir los nombres de variables a mayúsculas después de leer cada archivo. Esto ayuda a evitar errores por diferencias entre factor07, FACTOR07, conglome o CONGLOME.

m100 <- read_sav(file_100) |> as.data.frame()
m200 <- read_sav(file_200) |> as.data.frame()
m300 <- read_sav(file_300) |> as.data.frame()
m400 <- read_sav(file_400) |> as.data.frame()

names(m100) <- toupper(names(m100))
names(m200) <- toupper(names(m200))
names(m300) <- toupper(names(m300))
names(m400) <- toupper(names(m400))

6 Funciones auxiliares

Para que el código sea más legible, primero se definen algunas funciones pequeñas.

to_num <- function(x) {
  suppressWarnings(as.numeric(x))
}

si_1 <- function(x) {
  ifelse(x == 1, 1, 0)
}

departamento <- function(ubigeo) {
  ccdd <- substr(as.character(ubigeo), 1, 2)

  dplyr::case_when(
    ccdd == "01" ~ "AMAZONAS",
    ccdd == "02" ~ "ANCASH",
    ccdd == "03" ~ "APURIMAC",
    ccdd == "04" ~ "AREQUIPA",
    ccdd == "05" ~ "AYACUCHO",
    ccdd == "06" ~ "CAJAMARCA",
    ccdd == "07" ~ "CALLAO",
    ccdd == "08" ~ "CUSCO",
    ccdd == "09" ~ "HUANCAVELICA",
    ccdd == "10" ~ "HUANUCO",
    ccdd == "11" ~ "ICA",
    ccdd == "12" ~ "JUNIN",
    ccdd == "13" ~ "LA LIBERTAD",
    ccdd == "14" ~ "LAMBAYEQUE",
    ccdd == "15" ~ "LIMA",
    ccdd == "16" ~ "LORETO",
    ccdd == "17" ~ "MADRE DE DIOS",
    ccdd == "18" ~ "MOQUEGUA",
    ccdd == "19" ~ "PASCO",
    ccdd == "20" ~ "PIURA",
    ccdd == "21" ~ "PUNO",
    ccdd == "22" ~ "SAN MARTIN",
    ccdd == "23" ~ "TACNA",
    ccdd == "24" ~ "TUMBES",
    ccdd == "25" ~ "UCAYALI",
    TRUE ~ NA_character_
  )
}

7 Flujo general de trabajo

El proceso se puede resumir en tres pasos. Primero se define la configuración de estimación, luego se calculan las medidas de precisión y finalmente se exportan los resultados en el formato que se necesite.

svySE_cfg()

Configuración

Define estimador, nivel de confianza, tratamiento de PSU solitarias, valor objetivo y formato porcentual.

svySE_calc()

Cálculo

Usa indicadores, grupos, estratos, conglomerados y ponderadores para estimar errores muestrales.

svySE_xlsx()

Exportación

Genera tablas completas o personalizadas en Excel para revisión técnica o presentación de resultados.

8 Configuración común de svySE

En todos los indicadores se trabajará con variables binarias codificadas como 0 y 1, donde 1 representa la presencia de la carencia, condición o respuesta de interés.

cfg <- svySE_cfg(
  estimator = "prop",
  variance = "taylor",
  lonely_psu = "adjust",
  conf_level = 0.95,
  target = 1,
  valid_values = c(0, 1),
  truncate_lower_ci = TRUE,
  pct_mult = 100,
  deff = TRUE,
  cv = TRUE,
  na_rm = TRUE
)
print(cfg)
#> svySE configuration
#> --------------------------------------------------
#> Estimator          : prop 
#> Variance           : taylor 
#> Lonely PSU         : adjust 
#> Confidence level   : 0.95 
#> Target value       : 1 
#> Valid values       : 0, 1 
#> Truncate lower CI  : TRUE 
#> Percentage mult.   : 100 
#> Include DEFF       : TRUE 
#> Include CV         : TRUE 
#> Remove NA          : TRUE

Con esta configuración, svySE calcula proporciones, pero las presenta multiplicadas por 100. Por eso, en este documento los indicadores se construyen como 0/1, no como 0/100.

9 Indicadores considerados

Este ejemplo considera diez indicadores incluidos en la ficha técnica oficial:

Código Dimensión Indicador
1 Salud Población con carencia de atención médica
3 Salud Población con enfermedades crónicas
7 Educación Tasa neta de inasistencia escolar de la población de 3 a 16 años
8 Educación Carencia en logro educativo en personas de 17 años o más
13 Educación Calificación negativa de la infraestructura del centro de educación básica
14 Educación Calificación negativa del equipamiento del centro de educación básica
15 Vivienda y entorno Población en viviendas con hacinamiento
16 Vivienda y entorno Población en viviendas con piso de tierra
22 Energía Población que usa combustibles sólidos contaminantes
29 Conectividad Población de 6 años o más que no hace uso de internet

10 Construcción de indicadores de salud

Los indicadores de salud se construyen usando el módulo 400. En ambos casos se restringe el cálculo a miembros del hogar.

10.1 Indicador 1: carencia de atención médica

Este indicador identifica a la población que presentó algún problema de salud en las últimas cuatro semanas y que no accedió a una atención médica adecuada, ya sea porque se atendió en un lugar no adecuado o porque no buscó atención por razones distintas a que el problema no era grave o no era necesario.

salud <- m400 |>
  mutate(
    NOMBREDD = departamento(UBIGEO),
    FACTOR = to_num(FACTOR07),
    ESTRATO = as.character(ESTRATO),
    CONGLOME = as.character(CONGLOME),

    MIEPERHO = ifelse(P204 == 1 & !(P203 %in% c(8, 9)) & CODINFOR != "00", 1, 0),

    PROB_SALUD = ifelse(
      P4021 == 1 | P4022 == 1 | P4023 == 1 | P4024 == 1 | P4026 == 1,
      1, 0
    ),

    RAZON_FUERZA = ifelse(
      P4091 == 1 | P4092 == 1 | P4093 == 1 | P4094 == 1 |
        P4096 == 1 | P4097 == 1 | P4098 == 1 | P4099 == 1 |
        P40910 == 1 | P40911 == 1,
      1, 0
    ),

    IND_01_ATENCION_MEDICA = case_when(
      PROB_SALUD == 1 & (P40310 == 1 | P40311 == 1 | P40313 == 1 |
                           (P40314 == 1 & RAZON_FUERZA == 1)) ~ 1,
      PROB_SALUD == 0 ~ 0,
      PROB_SALUD == 1 & P40310 == 0 & P40311 == 0 & P40313 == 0 &
        (P40314 == 0 | (P40314 == 1 & RAZON_FUERZA == 0)) ~ 0,
      TRUE ~ NA_real_
    )
  ) |>
  filter(MIEPERHO == 1)

10.2 Indicador 3: enfermedades crónicas

Este indicador mide la proporción de población que declara padecer alguna enfermedad o malestar crónico.

salud <- salud |>
  mutate(
    IND_03_CRONICO = case_when(
      P401 == 1 ~ 1,
      P401 == 2 ~ 0,
      TRUE ~ NA_real_
    )
  )

10.3 Errores muestrales de los indicadores de salud

res_salud <- svySE_calc(
  data = salud,
  indicators = c(
    "IND_01_ATENCION_MEDICA",
    "IND_03_CRONICO"
  ),
  group_vars = "NOMBREDD",
  group_labels = "DEPARTAMENTO",
  strata = "ESTRATO",
  cluster = "CONGLOME",
  weight = "FACTOR",
  division = NULL,
  div_weight = NULL,
  cfg = cfg,
  verbose = TRUE
)

res_salud
#> svySE result
#> --------------------------------------------------
#> Indicators : IND_01_ATENCION_MEDICA, IND_03_CRONICO 
#> Groups     : NOMBREDD 
#> Strata     : ESTRATO 
#> Cluster    : CONGLOME 
#> Weight     : FACTOR 
#> Division   : NULL 
#> Estimator  : prop 
#> Target     : 1 
#> Strict     : FALSE

Ejemplo de como consultar los resultados sin exportar un archivo xlsx.

print(res_salud$results$IND_01_ATENCION_MEDICA)
#> $error
#> $error$TOTAL
#>         NOMBREDD     est_abs  est_pct     se_abs    se_pct    ci_l_abs ci_l_pct
#> 1       NACIONAL 10512722.45 31.16785 168006.653 0.3439787 10183435.46 30.49366
#> 2       AMAZONAS   160704.84 36.58325  14492.687 1.2531523   132299.70 34.12711
#> 3         ANCASH   500542.64 42.05105  40506.290 1.1376009   421151.77 39.82140
#> 4       APURIMAC   162777.98 33.79699  18181.118 1.4417238   127143.64 30.97127
#> 5       AREQUIPA   468573.86 33.90894  41167.531 1.3206437   387886.98 31.32053
#> 6       AYACUCHO   305357.59 40.93815  29523.301 1.2635124   247492.98 38.46171
#> 7      CAJAMARCA   608971.80 39.18900  50678.482 1.3355511   509643.80 36.57137
#> 8         CALLAO   239580.49 21.56341  23771.484 1.3302312   192989.24 18.95621
#> 9          CUSCO   465484.72 33.65757  41016.877 1.2217193   385093.11 31.26305
#> 10  HUANCAVELICA   201319.66 38.33125  19642.902 1.1757206   162820.28 36.02688
#> 11       HUANUCO   358874.87 39.42528  34641.319 1.4169634   290979.13 36.64808
#> 12           ICA   295597.76 35.16469  24038.633 1.0811666   248482.90 33.04564
#> 13         JUNIN   551887.36 38.60053  46011.116 1.2845711   461707.23 36.08281
#> 14   LA LIBERTAD   647197.72 31.87925  48772.868 0.8972129   551604.65 30.12074
#> 15    LAMBAYEQUE   428124.24 32.13508  35152.236 1.0442009   359227.12 30.08848
#> 16          LIMA  2583738.72 23.51452 131594.308 0.7722549  2325818.61 22.00093
#> 17        LORETO   285904.29 25.64492  25523.366 1.0867464   235879.41 23.51494
#> 18 MADRE DE DIOS    48496.61 30.17593   7637.235 2.0327119    33527.91 26.19189
#> 19      MOQUEGUA    62159.70 32.58579   6185.914 1.4885448    50035.53 29.66830
#> 20         PASCO   136680.97 42.57750  15355.726 1.6221229   106584.30 39.39820
#> 21         PIURA   509470.44 25.98165  38549.398 0.9297887   433915.01 24.15930
#> 22          PUNO   861020.04 55.40114  81270.599 1.5782426   701732.59 52.30784
#> 23    SAN MARTIN   273650.70 29.81349  24998.396 1.2285269   224654.74 27.40562
#> 24         TACNA    98940.90 26.70438  11149.003 1.2668439    77089.26 24.22141
#> 25        TUMBES    45253.37 17.72026   5294.067 1.1516988    34877.19 15.46297
#> 26       UCAYALI   212411.20 39.32331  19844.852 1.3557654   173516.01 36.66606
#>       ci_u_abs ci_u_pct       cv       deff n_unw
#> 1  10842009.44 31.84203 1.103633  6.3039272 36443
#> 2    189109.99 39.03938 3.425481  1.0076417  1504
#> 3    579933.51 44.28071 2.705285  2.1421977  1969
#> 4    198412.31 36.62272 4.265835  1.5162259   928
#> 5    549260.74 36.49736 3.894677  3.6443171  1705
#> 6    363222.19 43.41459 3.086394  1.6689458  1363
#> 7    708299.80 41.80664 3.407974  3.9413554  1789
#> 8    286171.74 24.17062 6.168927  3.9390362   771
#> 9    545876.32 36.05210 3.629850  3.1327755  1283
#> 10   239819.04 40.63562 3.067264  1.0407855  1283
#> 11   426770.61 42.20248 3.594048  2.5933271  1594
#> 12   342712.61 37.28374 3.074580  1.4604919  1603
#> 13   642067.49 41.11824 3.327859  3.3732892  1725
#> 14   742790.78 33.63775 2.814411  2.5501774  1643
#> 15   497021.35 34.18167 3.249411  2.2572092  1596
#> 16  2841658.82 25.02811 3.284161 12.3468599  3470
#> 17   335929.17 27.77490 4.237667  2.3399238  1474
#> 18    63465.32 34.15997 6.736203  1.0680080   567
#> 19    74283.87 35.50329 4.568079  0.6520226   911
#> 20   166777.64 45.75680 3.809812  1.1707686  1205
#> 21   585025.87 27.80401 3.578635  2.9871186  1554
#> 22  1020307.49 58.49443 2.848755  5.3093039  1727
#> 23   322646.65 32.22135 4.120709  2.2434928  1407
#> 24   120792.55 29.18735 4.743956  1.0294781  1106
#> 25    55629.55 19.97755 6.499334  0.7872882   542
#> 26   251306.40 41.98056 3.447740  1.4101408  1724
#> 
#> 
#> $simple
#> $simple$TOTAL
#>         NOMBREDD freq_0    pct_0 freq_1    pct_1 freq_total pct_total
#> 1       NACIONAL  77472 68.00860  36443 31.99140     113915       100
#> 2       AMAZONAS   2799 65.04764   1504 34.95236       4303       100
#> 3         ANCASH   2646 57.33478   1969 42.66522       4615       100
#> 4       APURIMAC   1972 68.00000    928 32.00000       2900       100
#> 5       AREQUIPA   3260 65.65962   1705 34.34038       4965       100
#> 6       AYACUCHO   2055 60.12288   1363 39.87712       3418       100
#> 7      CAJAMARCA   2795 60.97295   1789 39.02705       4584       100
#> 8         CALLAO   2780 78.28781    771 21.71219       3551       100
#> 9          CUSCO   2553 66.55370   1283 33.44630       3836       100
#> 10  HUANCAVELICA   2067 61.70149   1283 38.29851       3350       100
#> 11       HUANUCO   2481 60.88344   1594 39.11656       4075       100
#> 12           ICA   3329 67.49797   1603 32.50203       4932       100
#> 13         JUNIN   2957 63.15677   1725 36.84323       4682       100
#> 14   LA LIBERTAD   3691 69.19760   1643 30.80240       5334       100
#> 15    LAMBAYEQUE   3514 68.76712   1596 31.23288       5110       100
#> 16          LIMA  11643 77.03963   3470 22.96037      15113       100
#> 17        LORETO   4509 75.36353   1474 24.63647       5983       100
#> 18 MADRE DE DIOS   1409 71.30567    567 28.69433       1976       100
#> 19      MOQUEGUA   1839 66.87273    911 33.12727       2750       100
#> 20         PASCO   1680 58.23224   1205 41.76776       2885       100
#> 21         PIURA   4448 74.10863   1554 25.89137       6002       100
#> 22          PUNO   1534 47.04079   1727 52.95921       3261       100
#> 23    SAN MARTIN   3392 70.68139   1407 29.31861       4799       100
#> 24         TACNA   2853 72.06365   1106 27.93635       3959       100
#> 25        TUMBES   2454 81.90921    542 18.09079       2996       100
#> 26       UCAYALI   2812 61.99295   1724 38.00705       4536       100

11 Construcción de indicadores de educación y conectividad

Los indicadores de educación y conectividad se trabajan a partir del módulo 300. Para estos indicadores se usa el factor ajustado de población cuando corresponde.

11.1 Indicador 7: inasistencia escolar de 3 a 16 años

El indicador identifica a la población de 3 a 16 años que no asiste al sistema educativo o no asiste al nivel educativo que le corresponde según su edad.

educ <- m300 |>
  mutate(
    NOMBREDD = departamento(UBIGEO),
    FACTOR = to_num(FACTORA07),
    ESTRATO = as.character(ESTRATO),
    CONGLOME = as.character(CONGLOME),
    MES_NUM = to_num(MES),

    MIEPERHO = ifelse(P204 == 1 & !(P203 %in% c(8, 9)) & CODINFOR != "00", 1, 0),

    POB_INICIAL = ifelse(MIEPERHO == 1 & P208A >= 3 & P208A <= 5 & MES_NUM >= 4, 1, 0),
    ASISTE_INICIAL = ifelse(P306 == 1 & P307 == 1 & P308A == 1 & POB_INICIAL == 1, 1, 0),

    POB_PRIMARIA = ifelse(MIEPERHO == 1 & P208A >= 6 & P208A <= 11 & MES_NUM >= 4, 1, 0),
    ASISTE_PRIMARIA = ifelse(P306 == 1 & P307 == 1 & P308A %in% c(2, 7) & POB_PRIMARIA == 1, 1, 0),

    POB_SECUNDARIA = ifelse(MIEPERHO == 1 & P208A >= 12 & P208A <= 16 & MES_NUM >= 4, 1, 0),
    ASISTE_SECUNDARIA = ifelse(P306 == 1 & P307 == 1 & P308A == 3 & POB_SECUNDARIA == 1, 1, 0),

    POB_3_16 = ifelse(MIEPERHO == 1 & P208A >= 3 & P208A <= 16 & MES_NUM >= 4, 1, 0),

    IND_07_INASISTENCIA = case_when(
      POB_3_16 == 1 &
        (ASISTE_INICIAL == 1 | ASISTE_PRIMARIA == 1 | ASISTE_SECUNDARIA == 1) ~ 0,
      POB_3_16 == 1 ~ 1,
      TRUE ~ NA_real_
    )
  )

11.2 Indicador 8: carencia en logro educativo

Este indicador se calcula para personas de 17 años o más. La condición depende del año de nacimiento aproximado y del nivel educativo mínimo esperado.

educ <- educ |>
  mutate(
    ANIO_NUM = to_num(AÑO),
    NACIMIENTO = ANIO_NUM - P208A,
    EDAD_1994 = 1994 - NACIMIENTO,

    IND_08_LOGRO_EDUCATIVO = case_when(
      P208A >= 17 & EDAD_1994 >= 13 & P301A < 4 &
        (P306 == 2 | (P306 == 1 & P307 == 2) | P302A == 2) ~ 1,

      P208A >= 17 & EDAD_1994 >= 13 &
        ((P301A >= 4 & P301A != 12) | (P301A < 4 & (P307 == 1 | P302A == 1))) ~ 0,

      P208A >= 17 & EDAD_1994 < 13 & P301A < 6 &
        (P306 == 2 | (P306 == 1 & P307 == 2) | P302A == 2) ~ 1,

      P208A >= 17 & EDAD_1994 < 13 &
        ((P301A >= 6 & P301A != 12) | (P301A < 6 & (P307 == 1 | P302A == 1))) ~ 0,

      P208A >= 17 & P301A == 12 & (P301B < 6 | P301C < 6) &
        (P306 == 2 | P307 == 2) ~ 1,

      P208A >= 17 & P301A == 12 &
        (((P301B < 6 | P301C < 6) & P307 == 1) | (P301B == 6 | P301C == 6)) ~ 0,

      TRUE ~ NA_real_
    )
  )

11.3 Indicadores 13 y 14: infraestructura y equipamiento educativo

Estos indicadores se calculan para personas que asisten a educación básica regular. Se codifica como 1 cuando la evaluación del servicio es negativa.

educ <- educ |>
  mutate(
    MIEPERHO_EBR = ifelse(
      P204 == 1 & !(P203 %in% c(8, 9)) & CODINFOR != "00" &
        P307 == 1 & P308A %in% c(1, 2, 3, 7),
      1, 0
    ),

    IND_13_INFRAESTRUCTURA = case_when(
      MIEPERHO_EBR == 1 & P308B1 %in% c(1, 2) ~ 1,
      MIEPERHO_EBR == 1 & P308B1 %in% c(3, 4, 5) ~ 0,
      TRUE ~ NA_real_
    ),

    IND_14_EQUIPAMIENTO = case_when(
      MIEPERHO_EBR == 1 & P308B2 %in% c(1, 2) ~ 1,
      MIEPERHO_EBR == 1 & P308B2 %in% c(3, 4, 5) ~ 0,
      TRUE ~ NA_real_
    )
  )

11.4 Indicador 29: no uso de internet

Este indicador se calcula para población de 6 años o más. Se codifica como 1 cuando la persona no hace uso de internet.

educ <- educ |>
  mutate(
    MIEPERHO_6MAS = ifelse(
      P204 == 1 & !(P203 %in% c(8, 9)) & CODINFOR != "00" &
        P208A >= 6 & P208A <= 98,
      1, 0
    ),

    IND_29_SIN_INTERNET = case_when(
      MIEPERHO_6MAS == 1 & P314A == 1 ~ 0,
      MIEPERHO_6MAS == 1 & P314A == 2 ~ 1,
      TRUE ~ NA_real_
    )
  )

11.5 Errores muestrales de educación y conectividad

res_educ <- svySE_calc(
  data = educ,
  indicators = c(
    "IND_07_INASISTENCIA",
    "IND_08_LOGRO_EDUCATIVO",
    "IND_13_INFRAESTRUCTURA",
    "IND_14_EQUIPAMIENTO",
    "IND_29_SIN_INTERNET"
  ),
  group_vars = "NOMBREDD",
  group_labels = "DEPARTAMENTO",
  strata = "ESTRATO",
  cluster = "CONGLOME",
  weight = "FACTOR",
  division = NULL,
  div_weight = NULL,
  cfg = cfg,
  verbose = TRUE
)

res_educ
#> svySE result
#> --------------------------------------------------
#> Indicators : IND_07_INASISTENCIA, IND_08_LOGRO_EDUCATIVO, IND_13_INFRAESTRUCTURA, IND_14_EQUIPAMIENTO, IND_29_SIN_INTERNET 
#> Groups     : NOMBREDD 
#> Strata     : ESTRATO 
#> Cluster    : CONGLOME 
#> Weight     : FACTOR 
#> Division   : NULL 
#> Estimator  : prop 
#> Target     : 1 
#> Strict     : FALSE

12 Construcción de indicadores de vivienda y energía

Los indicadores de vivienda y energía requieren combinar información del módulo 100 con el módulo 200. La lógica general es construir primero la condición a nivel de vivienda u hogar y luego asignarla a las personas que pertenecen a esa vivienda u hogar.

12.1 Indicador 15: hacinamiento

El indicador considera que una vivienda presenta hacinamiento cuando hay más de tres personas por habitación, sin contar baño, cocina, pasadizos ni garaje.

habitaciones <- m100 |>
  filter(RESULT <= 2) |>
  mutate(
    TOTHAB = ifelse(P104 == 0, 1, P104)
  ) |>
  group_by(AÑO, CONGLOME, VIVIENDA) |>
  summarise(
    TOTHAB = sum(TOTHAB, na.rm = TRUE),
    .groups = "drop"
  )

personas_viv <- m200 |>
  mutate(MIEPERVIV = ifelse(P204 == 1, 1, 0)) |>
  filter(MIEPERVIV == 1) |>
  group_by(AÑO, CONGLOME, VIVIENDA) |>
  summarise(
    MIEPERVIV = sum(MIEPERVIV, na.rm = TRUE),
    .groups = "drop"
  )

hacinamiento <- habitaciones |>
  left_join(personas_viv, by = c("AÑO", "CONGLOME", "VIVIENDA")) |>
  mutate(
    IND_15_HACINAMIENTO = ifelse((MIEPERVIV / TOTHAB) > 3, 1, 0)
  ) |>
  select(AÑO, CONGLOME, VIVIENDA, IND_15_HACINAMIENTO)

12.2 Indicador 16: piso de tierra

Este indicador identifica a la población que vive en viviendas donde el material predominante de los pisos es tierra.

piso_tierra <- m100 |>
  filter(RESULT <= 2) |>
  mutate(
    IND_16_PISO_TIERRA = case_when(
      P103 == 6 ~ 1,
      !is.na(P103) & P103 != 6 ~ 0,
      TRUE ~ NA_real_
    )
  ) |>
  group_by(AÑO, CONGLOME, VIVIENDA) |>
  summarise(
    IND_16_PISO_TIERRA = max(IND_16_PISO_TIERRA, na.rm = TRUE),
    .groups = "drop"
  )

12.3 Indicador 22: combustibles sólidos contaminantes

El indicador identifica a la población que vive en hogares donde se usa carbón, leña, bosta, estiércol u otro combustible sólido contaminante para cocinar.

combustible <- m100 |>
  mutate(
    IND_22_COMBUSTIBLE = case_when(
      P1135 == 1 | P1136 == 1 | P1137 == 1 | P1139 == 1 ~ 1,
      !is.na(P1131) ~ 0,
      TRUE ~ NA_real_
    )
  ) |>
  select(AÑO, CONGLOME, VIVIENDA, HOGAR, FACTOR07, IND_22_COMBUSTIBLE)

12.4 Base integrada de vivienda y energía

viv_energia <- m200 |>
  left_join(hacinamiento, by = c("AÑO", "CONGLOME", "VIVIENDA")) |>
  left_join(piso_tierra, by = c("AÑO", "CONGLOME", "VIVIENDA")) |>
  left_join(combustible, by = c("AÑO", "CONGLOME", "VIVIENDA", "HOGAR")) |>
  mutate(
    NOMBREDD = departamento(UBIGEO),
    ESTRATO = as.character(ESTRATO),
    CONGLOME = as.character(CONGLOME),

    FACTOR = dplyr::coalesce(
      to_num(FACTOR07),
      to_num(FACPOB07)
    ),

    MIEPERHO = ifelse(P204 == 1 & !(P203 %in% c(8, 9)), 1, 0)
  ) |>
  filter(MIEPERHO == 1)

12.5 Errores muestrales de vivienda y energía

res_viv <- svySE_calc(
  data = viv_energia,
  indicators = c(
    "IND_15_HACINAMIENTO",
    "IND_16_PISO_TIERRA",
    "IND_22_COMBUSTIBLE"
  ),
  group_vars = "NOMBREDD",
  group_labels = "DEPARTAMENTO",
  strata = "ESTRATO",
  cluster = "CONGLOME",
  weight = "FACTOR",
  division = NULL,
  div_weight = NULL,
  cfg = cfg,
  verbose = TRUE
)

res_viv
#> svySE result
#> --------------------------------------------------
#> Indicators : IND_15_HACINAMIENTO, IND_16_PISO_TIERRA, IND_22_COMBUSTIBLE 
#> Groups     : NOMBREDD 
#> Strata     : ESTRATO 
#> Cluster    : CONGLOME 
#> Weight     : FACTOR 
#> Division   : NULL 
#> Estimator  : prop 
#> Target     : 1 
#> Strict     : FALSE

13 Exportación de resultados

Una vez calculados los objetos de resultado, svySE permite exportar dos tipos de tablas:

  1. una tabla de errores muestrales;
  2. una tabla simple con frecuencias y porcentajes no ponderados.

El siguiente ejemplo exporta las tablas de salud:

svySE_xlsx(
  x = res_salud,
  file_err = "[Errores Muestrales] ENAHO_2022_Salud.xlsx",
  file_tab = "[Simples] ENAHO_2022_Salud.xlsx",
  cols_err = svySE_cols_err("full"),
  cols_tab = svySE_cols_tab("full"),
  start_row = 10,
  overwrite = TRUE,
  keep_na = FALSE
)

De forma análoga se pueden exportar las tablas de educación, conectividad, vivienda y energía:

svySE_xlsx(
  x = res_educ,
  file_err = "[Errores Muestrales] ENAHO_2022_Educacion_Conectividad.xlsx",
  file_tab = "[Simples] ENAHO_2022_Educacion_Conectividad.xlsx",
  cols_err = svySE_cols_err("full"),
  cols_tab = svySE_cols_tab("full"),
  start_row = 10,
  overwrite = TRUE,
  keep_na = FALSE
)

svySE_xlsx(
  x = res_viv,
  file_err = "[Errores Muestrales] ENAHO_2022_Vivienda_Energia.xlsx",
  file_tab = "[Simples] ENAHO_2022_Vivienda_Energia.xlsx",
  cols_err = svySE_cols_err("full"),
  cols_tab = svySE_cols_tab("full"),
  start_row = 10,
  overwrite = TRUE,
  keep_na = FALSE
)

13.1 Exportación personalizada

Valor práctico. Esta parte es clave cuando el objetivo no es solo calcular, sino preparar tablas listas para ser revisadas o incorporadas en un reporte. En lugar de eliminar columnas manualmente en Excel, se define desde R qué columnas se quieren conservar.

En la práctica, no siempre se necesita exportar todas las columnas disponibles. A veces se requiere una tabla completa para revisión metodológica, mientras que en otros casos basta con un reporte más compacto para presentar porcentajes, errores estándar, intervalos de confianza y CV. Por eso, svySE_xlsx() permite personalizar la salida mediante cols_err y cols_tab.

La función svySE_cols_err() controla las columnas de la tabla de errores muestrales. Por ejemplo, la opción "full" exporta todas las medidas disponibles: estimación ponderada, porcentaje, error estándar, intervalos de confianza, CV, DEFF y recuento no ponderado.

svySE_cols_err("full")

Cuando se desea una salida más breve, se puede elegir un conjunto personalizado de columnas. Esto es útil para reportes donde el interés principal está en el porcentaje estimado y sus medidas de precisión.

columnas_error <- svySE_cols_err(
  type = "custom",
  cols = c(
    "est_pct",
    "se_pct",
    "ci_l_pct",
    "ci_u_pct",
    "cv",
    "deff",
    "n_unw"
  )
)

columnas_tabla <- svySE_cols_tab(
  type = "custom",
  cols = c(
    "freq_1",
    "pct_1",
    "freq_total",
    "pct_total"
  )
)

Con esas columnas se puede generar un archivo más ligero, pensado para revisión rápida o para anexos de reporte.

svySE_xlsx(
  x = res_salud,
  file_err = "[Errores Muestrales] ENAHO_2022_Salud_personalizado.xlsx",
  file_tab = "[Simples] ENAHO_2022_Salud_personalizado.xlsx",
  cols_err = columnas_error,
  cols_tab = columnas_tabla,
  start_row = 10,
  overwrite = TRUE,
  keep_na = FALSE
)

El argumento start_row permite dejar filas libres al inicio de la hoja. Esto es útil cuando se desea agregar posteriormente un encabezado institucional, notas metodológicas, fecha de procesamiento o información sobre la fuente de datos. Por ejemplo, start_row = 10 deja nueve filas disponibles antes de la tabla.

También se puede usar una exportación orientada solo a porcentajes. Este formato es conveniente cuando el producto final prioriza indicadores comparables entre departamentos o dominios de análisis.

svySE_xlsx(
  x = res_educ,
  file_err = "[Errores Muestrales] ENAHO_2022_Educacion_porcentajes.xlsx",
  file_tab = "[Simples] ENAHO_2022_Educacion_porcentajes.xlsx",
  cols_err = svySE_cols_err(
    type = "custom",
    cols = c(
      "est_pct",
      "se_pct",
      "ci_l_pct",
      "ci_u_pct",
      "cv",
      "n_unw"
    )
  ),
  cols_tab = svySE_cols_tab(
    type = "custom",
    cols = c(
      "freq_1",
      "pct_1",
      "freq_total"
    )
  ),
  start_row = 10,
  overwrite = TRUE,
  keep_na = FALSE
)

La exportación personalizada es una parte importante del flujo de trabajo porque conecta el cálculo estadístico con la presentación operativa de resultados. En lugar de editar manualmente cada tabla, el usuario puede definir una estructura común y aplicarla a varios indicadores, módulos o dimensiones de análisis.

14 Lectura de resultados

El producto más importante no es únicamente el porcentaje estimado. La ventaja de calcular errores muestrales es que cada indicador puede evaluarse junto con su precisión.

Por ejemplo, una tabla de errores muestrales generada por svySE puede incluir:

Columna Interpretación
est_abs estimación ponderada en frecuencia
est_pct porcentaje estimado
se_abs error estándar de la frecuencia
se_pct error estándar del porcentaje
ci_l_pct límite inferior del intervalo de confianza
ci_u_pct límite superior del intervalo de confianza
cv coeficiente de variación
deff efecto del diseño
n_unw recuento no ponderado

En un reporte institucional, estas columnas ayudan a decidir si una estimación es suficientemente estable para ser publicada, si requiere una nota de cautela o si debe interpretarse con especial cuidado.

15 Casos de uso

Este flujo puede ser útil en varios escenarios:

  • elaboración de cuadros de indicadores por departamento;
  • revisión de calidad estadística antes de publicar resultados;
  • comparación de indicadores entre dimensiones sociales;
  • construcción de reportes reproducibles en R Markdown;
  • generación de archivos Excel para revisión técnica;
  • documentación clara de la forma en que se construyen los indicadores.

También permite mantener separado el trabajo conceptual del trabajo operativo: primero se define claramente qué mide cada indicador y sobre qué población se calcula; después se usa una rutina común para estimar sus errores muestrales.

16 Comentarios finales

Este ejemplo muestra que R puede integrarse de manera natural en el proceso de construcción de indicadores ENAHO y en el cálculo de errores muestrales. La parte más importante sigue siendo la definición correcta del indicador: población objetivo, numerador, denominador y variable de ponderación. Una vez que esas piezas están claras, svySE ayuda a automatizar la parte repetitiva del proceso: calcular estimaciones, errores estándar, intervalos de confianza, CV, DEFF y recuentos no ponderados.

El propósito de este documento es dejar un flujo transparente y reutilizable. A partir de esta base, se pueden ampliar indicadores, incorporar más dominios de análisis o adaptar la salida a formatos institucionales específicos.

17 Referencias

Instituto Nacional de Estadística e Informática. Fichas técnicas de los indicadores generados a partir de la Encuesta Nacional de Hogares - ENAHO.
https://proyectos.inei.gob.pe/iinei/srienaho/Descarga/FichaTecnica/854-1788-Ficha.pdf

Burgos, L. svySE: Sampling Error Estimation for Complex Survey Indicators. R package.
https://github.com/lburgoss/svySE

sessionInfo()