12.2 Proceso de estimación en R
Para desarrollar la metodología se hace uso de las siguientes librerías.
# Interprete de STAN en R
library(rstan)
library(rstanarm)
# Manejo de bases de datos.
library(tidyverse)
# Gráficas de los modelos.
library(bayesplot)
library(patchwork)
# Organizar la presentación de las tablas
library(kableExtra)
library(printr)
Un conjunto de funciones desarrolladas para realizar de forma simplificada los procesos están consignadas en la siguiente rutina.
source("Recursos/Día4/Sesion2/0Recursos/funciones_mrp.R")
Entre las funciones incluidas en el archivo encuentra
plot_interaction: Esta crea un diagrama de lineas donde se estudia la interacción entre las variables, en el caso de presentar un traslape de las lineas se recomienda incluir el interacción en el modelo.
Plot_Compare Puesto que es necesario realizar una homologar la información del censo y la encuesta es conveniente llevar a cabo una validación de las variables que han sido homologadas, por tanto, se espera que las proporciones resultantes del censo y la encuesta estén cercanas entre sí.
Aux_Agregado: Esta es función permite obtener estimaciones a diferentes niveles de agregación, toma mucha relevancia cuando se realiza un proceso repetitivo.
Las funciones están diseñada específicamente para este proceso
12.2.1 Encuesta de hogares
Los datos empleados en esta ocasión corresponden a la ultima encuesta de hogares, la cual ha sido estandarizada por CEPAL y se encuentra disponible en BADEHOG
<- readRDS("Recursos/Día4/Sesion2/Data/encuestaDOM21N1.rds")
encuesta
<- encuesta %>%
encuesta_mrp transmute(
dam = haven::as_factor(dam_ee,levels = "values"),
dam = str_pad(string = dam, width = 2, pad = "0"),
dam2, ingreso = ingcorte, lp, li,
area = haven::as_factor(area_ee,levels = "values"),
area = case_when(area == 1 ~ "1", TRUE ~ "0"),
pobreza = ifelse(ingcorte < lp,1,0),
sexo = as.character(sexo),
anoest = case_when(
< 5 | anoest == -1 | is.na(anoest) ~ "98" , #No aplica
edad == 99 ~ "99", #NS/NR
anoest == 0 ~ "1", # Sin educacion
anoest %in% c(1:6) ~ "2", # 1 - 6
anoest %in% c(7:12) ~ "3", # 7 - 12
anoest > 12 ~ "4", # mas de 12
anoest TRUE ~ "Error" ),
edad = case_when(
< 15 ~ "1",
edad < 30 ~ "2",
edad < 45 ~ "3",
edad < 65 ~ "4",
edad TRUE ~ "5"),
fep = `_fep`
)
tba(encuesta_mrp %>% head(10))
dam | dam2 | ingreso | lp | li | area | pobreza | sexo | anoest | edad | fep |
---|---|---|---|---|---|---|---|---|---|---|
01 | 00101 | 54000.00 | 5622.81 | 3159.09 | 1 | 0 | 1 | 4 | 3 | 137.0652 |
01 | 00101 | 16388.89 | 5622.81 | 3159.09 | 1 | 0 | 2 | 3 | 4 | 137.0652 |
01 | 00101 | 16388.89 | 5622.81 | 3159.09 | 1 | 0 | 1 | 3 | 5 | 137.0652 |
01 | 00101 | 16388.89 | 5622.81 | 3159.09 | 1 | 0 | 1 | 4 | 2 | 137.0652 |
01 | 00101 | 6224.00 | 5622.81 | 3159.09 | 1 | 0 | 2 | 2 | 4 | 137.0652 |
01 | 00101 | 6224.00 | 5622.81 | 3159.09 | 1 | 0 | 1 | 3 | 3 | 137.0652 |
01 | 00101 | 6224.00 | 5622.81 | 3159.09 | 1 | 0 | 2 | 4 | 2 | 137.0652 |
01 | 00101 | 20672.00 | 5622.81 | 3159.09 | 1 | 0 | 2 | 1 | 5 | 137.0652 |
01 | 00101 | 8495.60 | 5622.81 | 3159.09 | 1 | 0 | 1 | 4 | 3 | 137.0652 |
01 | 00101 | 8495.60 | 5622.81 | 3159.09 | 1 | 0 | 2 | 3 | 3 | 137.0652 |
La base de datos de la encuesta tiene la siguientes columnas:
dam: Corresponde al código asignado a la división administrativa mayor del país.
dam2: Corresponde al código asignado a la segunda división administrativa del país.
lp y li lineas de pobreza y pobreza extrema definidas por CEPAL.
área división geográfica (Urbano y Rural).
sexo Hombre y Mujer.
etnia En estas variable se definen tres grupos: afrodescendientes, indígenas y Otros.
Años de escolaridad (anoest)
Rangos de edad (edad)
Factor de expansión por persona (fep)
Ahora, inspeccionamos el comportamiento de la variable de interés:
<- encuesta_mrp %>% group_by(pobreza) %>%
tab tally() %>%
mutate(prop = round(n/sum(n),2),
pobreza = ifelse(pobreza == 1, "Si", "No"))
ggplot(data = tab, aes(x = pobreza, y = prop)) +
geom_bar(stat = "identity") +
labs(y = "", x = "") +
geom_text(aes(label = paste(prop*100,"%")),
nudge_y=0.05) +
theme_bw(base_size = 20) +
theme(axis.text.y = element_blank(),
axis.ticks = element_blank())
Figura 12.1: Proporción de personas por debajo de la linea de pobreza
La información auxiliar disponible ha sido extraída del censo e imágenes satelitales
<-
statelevel_predictors_df readRDS("Recursos/Día4/Sesion2/Data/statelevel_predictors_df_dam2.rds") %>%
mutate_at(.vars = c("luces_nocturnas",
"cubrimiento_cultivo",
"cubrimiento_urbano",
"modificacion_humana",
"accesibilidad_hospitales",
"accesibilidad_hosp_caminado"),
function(x) as.numeric(scale(x)))
tba(statelevel_predictors_df %>% head(10))
dam2 | modificacion_humana | accesibilidad_hospitales | accesibilidad_hosp_caminado | cubrimiento_cultivo | cubrimiento_urbano | luces_nocturnas | area1 | sexo2 | edad2 | edad3 | edad4 | edad5 | anoest2 | anoest3 | anoest4 | anoest99 | tiene_sanitario | tiene_acueducto | tiene_gas | eliminar_basura | tiene_internet | piso_tierra | material_paredes | material_techo | rezago_escolar | alfabeta | hacinamiento | tasa_desocupacion | id_municipio |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
00101 | 3.6127 | -1.1835 | -1.5653 | -1.1560 | 7.2782 | 4.9650 | 1.0000 | 0.5224 | 0.2781 | 0.2117 | 0.1808 | 0.0725 | 0.2000 | 0.3680 | 0.2286 | 0.0193 | 0.0119 | 0.7946 | 0.0673 | 0.0810 | 0.6678 | 0.0033 | 0.0109 | 0.0111 | 0.3694 | 0.9247 | 0.1962 | 0.0066 | 100101 |
00201 | -0.0553 | 0.4449 | 0.2100 | 0.0684 | -0.0682 | -0.1511 | 0.8904 | 0.4933 | 0.2726 | 0.1849 | 0.1520 | 0.0614 | 0.3149 | 0.3022 | 0.0775 | 0.0082 | 0.1005 | 0.7220 | 0.2261 | 0.1300 | 0.9276 | 0.0664 | 0.0812 | 0.0249 | 0.1501 | 0.7975 | 0.3014 | 0.0007 | 050201 |
00202 | -0.3758 | 0.0000 | 0.1482 | -0.2345 | -0.2855 | -0.4234 | 0.6799 | 0.4697 | 0.2804 | 0.1895 | 0.1430 | 0.0515 | 0.3757 | 0.2405 | 0.0148 | 0.0014 | 0.1322 | 0.9230 | 0.2693 | 0.2884 | 0.9759 | 0.0625 | 0.0986 | 0.0673 | 0.0278 | 0.7140 | 0.3454 | 0.0001 | 050202 |
00203 | -0.9259 | 0.5732 | -0.1402 | -0.5511 | -0.3822 | -0.5612 | 0.5814 | 0.4601 | 0.2665 | 0.1733 | 0.1586 | 0.0713 | 0.3778 | 0.2463 | 0.0219 | 0.0052 | 0.2579 | 0.7602 | 0.4824 | 0.2589 | 0.9919 | 0.1937 | 0.2342 | 0.1238 | 0.0485 | 0.7104 | 0.2755 | 0.0001 | 050203 |
00204 | -1.3166 | 1.1111 | 0.4438 | -0.5027 | -0.3835 | -0.6042 | 0.5708 | 0.4663 | 0.2647 | 0.1683 | 0.1673 | 0.0757 | 0.3306 | 0.2402 | 0.0440 | 0.0049 | 0.1672 | 0.6375 | 0.5040 | 0.3837 | 0.9759 | 0.1403 | 0.1354 | 0.0176 | 0.0873 | 0.6737 | 0.2671 | 0.0002 | 050204 |
00205 | -0.7474 | 2.1155 | 1.2271 | -0.5838 | -0.3345 | -0.5909 | 0.6937 | 0.4633 | 0.2849 | 0.2107 | 0.1473 | 0.0583 | 0.2794 | 0.2821 | 0.0562 | 0.0067 | 0.3800 | 0.6596 | 0.5014 | 0.2852 | 0.9894 | 0.2309 | 0.2498 | 0.0459 | 0.1016 | 0.6751 | 0.4973 | 0.0001 | 050205 |
00206 | 0.5157 | -0.1468 | -0.1811 | 1.1894 | -0.1191 | -0.4022 | 0.9563 | 0.4557 | 0.2910 | 0.1814 | 0.1495 | 0.0626 | 0.3793 | 0.2815 | 0.0427 | 0.0052 | 0.1301 | 0.8817 | 0.2565 | 0.1495 | 0.9659 | 0.0629 | 0.0472 | 0.0337 | 0.0835 | 0.8027 | 0.2200 | 0.0001 | 050206 |
00207 | 1.7368 | -0.7648 | -0.4861 | 0.7170 | -0.0609 | 0.0042 | 0.5201 | 0.4783 | 0.2898 | 0.1675 | 0.1464 | 0.0531 | 0.3552 | 0.2901 | 0.0328 | 0.0061 | 0.2434 | 0.5775 | 0.2758 | 0.0950 | 0.9911 | 0.0717 | 0.2004 | 0.1304 | 0.0714 | 0.7778 | 0.3936 | 0.0001 | 050207 |
00208 | -0.5942 | 0.3212 | -0.1697 | -0.3627 | -0.3044 | -0.4750 | 0.6625 | 0.4334 | 0.2943 | 0.1875 | 0.1523 | 0.0654 | 0.3557 | 0.2486 | 0.0250 | 0.0054 | 0.1908 | 0.8251 | 0.4152 | 0.1450 | 0.9907 | 0.1458 | 0.1517 | 0.0852 | 0.0509 | 0.6897 | 0.3051 | 0.0001 | 050208 |
00209 | -1.5280 | 3.0192 | 1.9428 | -0.8078 | -0.4046 | -0.6423 | 0.6798 | 0.4311 | 0.2858 | 0.1687 | 0.1628 | 0.0701 | 0.3648 | 0.2645 | 0.0752 | 0.0061 | 0.1893 | 0.5760 | 0.4096 | 0.3557 | 0.9978 | 0.1097 | 0.0941 | 0.0292 | 0.1357 | 0.7680 | 0.2189 | 0.0001 | 050209 |
12.2.2 Niveles de agregación para colapsar la encuesta
Después de realizar una investigación en la literatura especializada y realizar estudios de simulación fue posible evidenciar que las predicciones obtenidas con la muestra sin agregar y la muestra agregada convergen a la media del dominio.
<- c("dam", "dam2", "area",
byAgrega "sexo", "anoest", "edad" )
12.2.3 Creando base con la encuesta agregada
El resultado de agregar la base de dato se muestra a continuación:
<-
encuesta_df_agg %>% # Encuesta
encuesta_mrp group_by_at(all_of(byAgrega)) %>% # Agrupar por el listado de variables
summarise(n = n(), # Número de observaciones
# conteo de personas con características similares.
pobreza = sum(pobreza),
no_pobreza = n-pobreza,
.groups = "drop") %>%
arrange(desc(pobreza)) # Ordenar la base.
La tabla obtenida es la siguiente:
dam | dam2 | area | sexo | anoest | edad | n | pobreza | no_pobreza |
---|---|---|---|---|---|---|---|---|
01 | 00101 | 1 | 2 | 3 | 2 | 624 | 221 | 403 |
32 | 03201 | 1 | 2 | 2 | 1 | 359 | 158 | 201 |
01 | 00101 | 1 | 1 | 2 | 1 | 401 | 155 | 246 |
32 | 03201 | 1 | 2 | 3 | 2 | 576 | 154 | 422 |
01 | 00101 | 1 | 2 | 2 | 1 | 348 | 148 | 200 |
32 | 03201 | 1 | 1 | 2 | 1 | 369 | 145 | 224 |
01 | 00101 | 1 | 1 | 3 | 2 | 652 | 135 | 517 |
32 | 03203 | 1 | 2 | 3 | 2 | 393 | 128 | 265 |
01 | 00101 | 1 | 1 | 98 | 1 | 302 | 127 | 175 |
25 | 02501 | 1 | 2 | 3 | 2 | 447 | 126 | 321 |
El paso a seguir es unificar las tablas creadas.
<- inner_join(encuesta_df_agg, statelevel_predictors_df) encuesta_df_agg
12.2.4 Definiendo el modelo multinivel.
Después de haber ordenado la encuesta, podemos pasar a la definición del modelo.
options(mc.cores = parallel::detectCores()) # Permite procesar en paralelo.
<- stan_glmer(
fit cbind(pobreza, no_pobreza) ~
1 | dam2) + # Efecto aleatorio (ud)
(+ # Efecto fijo (Variables X)
edad +
sexo +
tasa_desocupacion +
luces_nocturnas +
cubrimiento_cultivo
cubrimiento_urbano ,data = encuesta_df_agg, # Encuesta agregada
verbose = TRUE, # Muestre el avance del proceso
chains = 4, # Número de cadenas.
iter = 1000, # Número de realizaciones de la cadena
cores = 4,
family = binomial(link = "logit")
)saveRDS(fit, file = "Recursos/Día4/Sesion2/Data/fit_pobreza.rds")
Después de esperar un tiempo prudente se obtiene el siguiente modelo.
<- readRDS("Recursos/Día4/Sesion2/Data/fit_pobreza.rds") fit
Validación del modelo
library(posterior)
library(bayesplot)
<- c("edad2", "edad3", "edad4", "edad5", "sexo2",
var_names "luces_nocturnas", "cubrimiento_cultivo","cubrimiento_urbano")
mcmc_areas(fit,pars = var_names)
mcmc_trace(fit,pars = var_names)
<- inner_join(encuesta_mrp, statelevel_predictors_df)
encuesta_mrp2 <- posterior_epred(fit, newdata = encuesta_mrp2)
y_pred_B <- sample(nrow(y_pred_B), 100)
rowsrandom <- y_pred_B[rowsrandom, ]
y_pred2 ppc_dens_overlay(y = as.numeric(encuesta_mrp2$pobreza), y_pred2)
Figura 12.2: Tasa de pobreza por dam2
Los coeficientes del modelo para las primeras dam2 son:
(Intercept) | edad2 | edad3 | edad4 | edad5 | sexo2 | tasa_desocupacion | luces_nocturnas | cubrimiento_cultivo | cubrimiento_urbano | |
---|---|---|---|---|---|---|---|---|---|---|
00101 | -0.7843 | -0.7164 | -0.7355 | -1.5045 | -1.6397 | 0.2901 | 8.0861 | -0.2643 | -0.0691 | 0.197 |
00201 | -0.8704 | -0.7164 | -0.7355 | -1.5045 | -1.6397 | 0.2901 | 8.0861 | -0.2643 | -0.0691 | 0.197 |
00202 | -0.5086 | -0.7164 | -0.7355 | -1.5045 | -1.6397 | 0.2901 | 8.0861 | -0.2643 | -0.0691 | 0.197 |
00203 | -0.2080 | -0.7164 | -0.7355 | -1.5045 | -1.6397 | 0.2901 | 8.0861 | -0.2643 | -0.0691 | 0.197 |
00204 | -0.9745 | -0.7164 | -0.7355 | -1.5045 | -1.6397 | 0.2901 | 8.0861 | -0.2643 | -0.0691 | 0.197 |
00205 | -0.5200 | -0.7164 | -0.7355 | -1.5045 | -1.6397 | 0.2901 | 8.0861 | -0.2643 | -0.0691 | 0.197 |
00206 | -0.1536 | -0.7164 | -0.7355 | -1.5045 | -1.6397 | 0.2901 | 8.0861 | -0.2643 | -0.0691 | 0.197 |
00208 | -0.4769 | -0.7164 | -0.7355 | -1.5045 | -1.6397 | 0.2901 | 8.0861 | -0.2643 | -0.0691 | 0.197 |
00210 | -1.3939 | -0.7164 | -0.7355 | -1.5045 | -1.6397 | 0.2901 | 8.0861 | -0.2643 | -0.0691 | 0.197 |
00301 | 0.2809 | -0.7164 | -0.7355 | -1.5045 | -1.6397 | 0.2901 | 8.0861 | -0.2643 | -0.0691 | 0.197 |