logo_unam_enacif

Análisis de encuestas complejas

Julio César Martínez Sánchez


Introducción

Este curso brinda los fundamentos del muestreo estadístico, lo que permite a los participantes evaluar la calidad de los estimadores poblacionales de encuestas probabilísticas. Iniciamos con una introducción al diseño de muestras complejas, luego nos enfocamos en validar los estimadores poblacionales (totales, razones y proporciones) y terminamos con la implementación de modelos estadísticos. Para llevar a cabo los ejercicios, utilizamos como fuente de información a la muestra censal 2020, lo que garantiza un aprendizaje efectivo y aplicable al entorno real.

Todo el material de apoyo, incluyendo los scripts y bases de datos necesarias para replicar este tutorial, se puede encontrar en el siguiente: material



Muestra censal 2020

La estrategia de diseño muestral se define como el conjunto de técnicas utilizadas para crear una muestra representativa del universo de estudio. Este enfoque incluye la determinación de cuántas unidades de análisis se seleccionarán, cómo se van a elegir dichas unidades y el procedimiento para la recopilación de datos durante el trabajo de campo (Kish, 1965). Según el INEGI, el marco muestral utilizado para el diseño de la muestra censal 2020 se basó en datos provenientes del Censo de 2010, la Encuesta Intercensal de 2015 y los Censos Económicos, entre otras fuentes. Los estratos definidos para la muestra fueron dos: los municipios seleccionados con certeza y los municipios estratificados. Las Unidades Primarias de Muestreo (UPM), o conglomerados, se conformaron por conjuntos de manzanas, aplicando una afijación proporcional al número total de viviendas en los municipios (INEGI, 2020, p. 2). Gráficamente, esto se puede visualizar de la siguiente forma:

El esquema muestral influye directamente en la ponderación de los datos. En el caso de las viviendas de los municipios seleccionados con certeza, la probabilidad de selección (\(\pi_i\)) es igual a 1, por lo que el ponderador base (\(bw\)) se define de la siguiente manera:

\[\pi_i = 1 \rightarrow w_i = \frac{1}{\pi_i}=\frac{1}{1} = 1\]


En contraste, en aquellas viviendas donde solo se recopiló información de un subconjunto, la probabilidad asociada al muestreo supera el valor de 1. Tomemos, por ejemplo, el caso en el que se recoge información en una de cada diez viviendas. Bajo esta premisa, el ponderador base que es el inverso de la probabilidad de selección es igual a 10.

\[\pi_i = \frac{1}{10} \rightarrow w_i = \frac{1}{\pi_i}=\frac{1}{1/10} = 10\]


Esta disparidad en los ponderadores aumenta la varianza de los estimadores, lo cual, a su vez, afecta negativamente su precisión. Es por esta razón que resulta esencial validar la calidad de los estimadores para garantizar la fiabilidad de los resultados obtenidos.



Entorno de trabajo


Para generar estimadores utilizando datos de la muestra censal 2020 y evaluar su calidad, vamos a utilizar los siguientes paquetes:

  • tidyverse: Conjunto de paquetes para la manipulación y visualización de datos.
  • foreign: Permite leer y escribir datos de otros formatos estadísticos.
  • survey: Facilita el análisis de encuestas con diseños de muestreo complejos.
  • knitr: Herramienta para crear informes dinámicos y reproducibles con R.
  • kableExtra: Mejora las tablas generadas con knitr, añadiendo más opciones de formato y estilización.

Trabajaremos con la base de datos correspondiente a la muestra censal de Aguascalientes, denominada “Personas01.csv”.


rm(list=ls()); graphics.off(); options(warn=-1)              
paquetes <- c("tidyverse", "foreign", "survey","knitr","kableExtra")
for (i in paquetes) {if (!require(i, character.only = TRUE)) {install.packages(i);library(i, character.only = TRUE)} else {library(i, character.only = TRUE)}}


muestra_censal=read_csv("Personas01.csv")



1. Promedios


Para establecer el diseño de la encuesta haremos uso de la función svydesign. Comenzaremos especificando nuestro conjunto de datos, en este caso, muestra_censal. A continuación, utilizaremos id = ~UPM para identificar las Unidades Primarias de Muestreo (UPM). La opción strata = ~ESTRATO nos permite definir las estratificaciones dentro de nuestra muestra. Por otro lado, weights = ~FACTOR asigna la variable que actúa como ponderador o factor de expansión, el cual es esencial para ajustar los resultados a la población total. Finalmente, el parámetro nest = TRUE indica que las UPM pueden estar organizadas en estructuras más complejas, reconociendo así la presencia de niveles (o capas anidadas) dentro de la muestra.


svydesign(id = ~UPM, strata = ~ESTRATO, weight = ~FACTOR, data = muestra_censal, nest = TRUE)


Reconocemos que la muestra censal tiene un diseño muestral estratificado y por conglomerados, con múltiples etapas de selección. Sin embargo, para visualizar el efecto del diseño muestral en los estimadores vamos a simular cuatro escenarios distintos. En el primero asumiremos un muestreo aleatorio simple; en el segundo, un muestreo por conglomerados; en el tercero un muestreo estratificado y en el cuarto, abordaremos un muestreo complejo, que representa el diseño real de la muestra censal. Nuestro objetivo es comparar el coeficiente de variación en cada escenario para discernir cómo afecta el diseño estadístico en la calidad de los estimadores.

# Escenario 1: Muestreo aleatorio simple
ds_mc1 <- svydesign(id = ~1, data = muestra_censal)
svy1 <- svymean(~ESCOACUM, ds_mc1, na.rm=TRUE, deff = TRUE)
cv1 <- (cv(svy1) * 100) %>% round(3) %>% as.numeric()


# Escenario 2: Muestreo por conglomerados
ds_mc2 <- svydesign(id = ~UPM, weight = ~FACTOR, data = muestra_censal)
svy2 <- svymean(~ESCOACUM, ds_mc2, na.rm=TRUE, deff = TRUE)
cv2 <- (cv(svy2) * 100) %>% round(3) %>% as.numeric()


# Escenario 3: Muestreo estratificado
ds_mc3 <- svydesign(id = ~1, strata = ~ESTRATO, weight = ~FACTOR, data = muestra_censal, nest = TRUE)
svy3 <- svymean(~ESCOACUM, ds_mc3, na.rm=TRUE, deff = TRUE)
cv3 <- (cv(svy3) * 100) %>% round(3) %>% as.numeric()


# Escenario 4: Muestreo complejo
ds_mc4 <- svydesign(id = ~UPM, strata = ~ESTRATO, weight = ~FACTOR, data = muestra_censal, nest = TRUE)
svy4 <- svymean(~ESCOACUM, ds_mc4, na.rm=TRUE, deff = TRUE)
cv4 <- (cv(svy4) * 100) %>% round(3) %>% as.numeric()


comparacion <- t(c(cv1, cv2, cv3, cv4)) %>% 
  data.frame()
colnames(comparacion) <- c("Aleatorio simple", "Conglomerados", "Estratificado", "Complejo: conglomerados y estratificado")

resultados <- bind_rows(
  data.frame(Escenario = "Muestreo aleatorio simple", Estimador = coef(svy1)[[1]], CV = cv1),
  data.frame(Escenario = "Muestreo por conglomerados", Estimador = coef(svy2)[[1]], CV = cv2),
  data.frame(Escenario = "Muestreo estratificado", Estimador = coef(svy3)[[1]], CV = cv3),
  data.frame(Escenario = "Muestreo complejo", Estimador = coef(svy4)[[1]], CV = cv4)
)


Escenario Estimador CV
Muestreo aleatorio simple 8.015189 0.261
Muestreo por conglomerados 8.892341 1.621
Muestreo estratificado 8.892341 0.416
Muestreo complejo 8.892341 1.518



2. Totales


En el ejercicio previo nos enfocamos en calcular promedios. Ahora, vamos a expandir nuestro análisis generando un tipo diferente de estimadores: totales. Para ello, ajustamos el diseño de la muestra censal e incorporamos la instrucción options(survey.lonely.psu = "adjust"). Esta configuración es clave dentro del paquete survey, ya que nos permite especificar el tratamiento de las Unidades Primarias de Muestreo (UPM) aisladas, lo cual suele ocurrir cuando se tienen subpoblaciones muy pequeñas.

# Definición del diseño de la encuesta
ds_mc5 <- svydesign(id = ~UPM, strata = ~ESTRATO, weights = ~FACTOR, data = muestra_censal, nest = TRUE)
options(survey.lonely.psu = "adjust")


svy5=svytotal(~factor(AGUINALDO), ds_mc5, na.rm=TRUE, deff = TRUE) 
t0=(cv(svy5) * 100) %>% as.data.frame()
.
factor(AGUINALDO)1 4.747625
factor(AGUINALDO)2 5.516478



3. Proporciones

Para obtener proporciones el procedimiento inicial es el mismo, declaramos el esquema de muestreo y usamos la opción survey.lonely.psu. La diferencia es que, al tener dos valores, no podemos obtner el coeficiente de variación de forma directa, sino que lo calculamos manualmente.

ds_mc5 <- svydesign(id = ~UPM, strata = ~ESTRATO, weights = ~FACTOR, data = muestra_censal, nest = TRUE)
options(survey.lonely.psu = "adjust")


prop_sexo <- svymean(~factor(SEXO), ds_mc5, na.rm=TRUE, deff = TRUE)
prop_sexo <- as.data.frame(prop_sexo)

# Renombrar las columnas para hacerlas más legibles
colnames(prop_sexo) <- c("Proporción", "Error Estándar", "DEFF")
prop_sexo$CV <- (prop_sexo$"Error Estándar" / prop_sexo$"Proporción") * 100
Proporción Error Estándar DEFF CV
factor(SEXO)1 0.4858049 0.0023046 2.188503 0.4743813
factor(SEXO)3 0.5141951 0.0023046 2.188503 0.4481894



4. Modelo estadístico

El diseño muestral también influye en los modelos econométricos influyendo en los resultados. Esto se refleja en cómo el valor de los coeficientes y sus respectivos niveles de significancia varian al considerar -o no- el dieseño muestral. Para ilustrar este fenómeno, ejecutamos dos modelos de regresión lineal: el primero sin incorporar el diseño muestral y el segundo sí tomando en cuenta el diseño.

#Definir esquema de muestreo
ds_mc5 <- svydesign(id = ~UPM, strata = ~ESTRATO, weights = ~FACTOR, data = muestra_censal, nest = TRUE)
options(survey.lonely.psu = "adjust")

#Regresión lineal
modelo_1 <- glm(as.numeric(ESCOACUM) ~ as.factor(SEXO) + as.factor(PERTE_INDIGENA) + as.numeric(EDAD), data=muestra_censal)
summary(modelo_1)

modelo_2 <- svyglm(as.numeric(ESCOACUM) ~ as.factor(SEXO) + as.factor(PERTE_INDIGENA) + as.numeric(EDAD), design = ds_mc5)
summary(modelo_2)

# Comparación de modelos
comparacion_rl <- data.frame(
  Estimate_1 = round(coef(modelo_1), 2),
  Estimate_2 = round(coef(modelo_2), 2)
)

signif_1 <- summary(modelo_1)$coefficients[,4] 
signif_2 <- summary(modelo_2)$coefficients[,4] 

estrella <- function(p.value){
  if(p.value < 0.001) return("***")
  else if(p.value < 0.01) return("**")
  else if(p.value < 0.05) return("*")
  else if(p.value < 0.1) return(".")
  else return("")
}

comparacion_rl <- data.frame(
  Coef_1 = round(coef(modelo_1), 2),
  Sig_1 = sapply(signif_1, estrella),
  Coef_2 = round(coef(modelo_2), 2),
  Sig_2 = sapply(signif_2, estrella)
)

Así, los resultados de ambos modelos permiten apreciar claramente las diferencias en la magnitud de los coeficientes y en la significancia estadística de las variables. Esto subraya la importancia de ajustar nuestros métodos estadísticos al diseño de la muestra para obtener estimaciones confiables.

Coef_1 Sig_1 Coef_2 Sig_2
(Intercept) 6.50 *** 6.32 ***
as.factor(SEXO)3 0.19 *** 0.05
as.factor(PERTE_INDIGENA)3 -0.14 0.10
as.factor(PERTE_INDIGENA)9 4.09 *** 41.61
as.numeric(EDAD) 0.05 *** 0.08 ***



5. Subpoblaciones


5.1 Estimadores

Un enfoque común en la investigación sociodemográfica consiste en centrar el análisis en subpoblaciones específicas, especialmente cuando se desea estudiar un grupo con características distintivas. Es importante destacar la recomendación de NO ELIMINAR datos del conjunto inicial, ya que esta acción podría alterar de manera artificial el diseño muestral original. Esto se ilustra claramente en el ejemplo siguiente:


En lugar de eliminar datos, definiremos la subpoblación con la que deseamos trabajar, y para ello disponemos de dos opciones. La primera consiste en utilizar el comando svyby, y la segunda, en emplear subset para centrar nuestro análisis específicamente en la subpoblación de interés. Exploraremos el funcionamiento de estos comandos y evidenciaremos el efecto no deseado de eliminar datos del conjunto inicial. A modo de ejemplo, definiremos como subpoblación a las personas ocupadas que perciben un ingreso, tienen 20 años de edad y presentan discapacidad visual.

muestra_censal$b <- ifelse(muestra_censal$EDAD == 20 & muestra_censal$DIS_VER==1 & (muestra_censal$INGTRMEN>0 & muestra_censal$INGTRMEN<999997), 1, 0)


En el primer escenario, aplicaremos la opción svyby; en el segundo, recurriremos a subset. En el tercer escenario, adoptaremos el enfoque tradicional de eliminar datos del conjunto inicial antes de definir el esquema muestral. Los resultados obtenidos en términos del coeficiente de variación (cv) se presentan en una tabla final. Esta tabla evidencia que las opciones 1 y 2 generan un valor de cv similar, específicamente \(4.105433\), mientras que en el tercer escenario, el valor del cv difiere, siendo \(4.082324\). Este contraste resalta la importancia de seleccionar el método adecuado para el análisis de subpoblaciones en estudios sociodemográficos, demostrando cómo la eliminación de datos puede influir en los resultados.

muestra_censal$b <- ifelse(muestra_censal$EDAD == 20 & muestra_censal$DIS_VER==1 & (muestra_censal$INGTRMEN>0 & muestra_censal$INGTRMEN<999997), 1, 0)

ds_mc5 <- svydesign(id = ~UPM, strata = ~ESTRATO, weights = ~FACTOR, data = muestra_censal, nest = TRUE)
opcion_1 <- svyby(~INGTRMEN, ~b, ds_mc5, na.rm = TRUE, svymean) %>%
  as.data.frame() %>%
  rename(b = b, promedio = INGTRMEN, se = se) %>% 
  mutate(cv = (se / promedio) * 100) 
  


ds_mc5 <- svydesign(id = ~UPM, strata = ~ESTRATO, weights = ~FACTOR, data = muestra_censal, nest = TRUE)
ds_mc5_2<-subset(ds_mc5,b==1)

opcion_2 <- svymean(~INGTRMEN, ds_mc5_2, na.rm = TRUE, deff = TRUE) %>%
  as.data.frame() %>%
  rename(promedio = mean, se = INGTRMEN, deff = deff) %>%
  mutate(cv = (se / promedio) * 100)
  


# Ignoramos la adavertencia y recortamos la base
muestra_censal_recortada=subset(muestra_censal, b == 1)
ds_mc_con_muestra_recortada <- svydesign(id = ~UPM, strata = ~ESTRATO, weights = ~FACTOR, data = muestra_censal_recortada, nest = TRUE)

opcion_3 <- svymean(~INGTRMEN, ds_mc_con_muestra_recortada, na.rm = TRUE, deff = TRUE) %>%
  as.data.frame() %>%
  rename(promedio = mean, se = INGTRMEN, deff = deff) %>% 
  mutate(cv = (se / promedio) * 100)
  
cv_tabla <- data.frame(
  CV_o1 = opcion_1[2,4],
  CV_o2 = opcion_2$cv,
  CV_recortando = opcion_3$cv
)


CV_o1 CV_o2 CV_recortando
4.105433 4.105433 4.082324



5.2 Modelos estadísticos

Modificar la base de datos es equivalente a cambiar el diseño muestral, lo cual puede alterar de manera significativa los resultados de los modelos econométricos. Para ejemplificar esta situación proponemos dos escenarios: en el modelo 3 quitamos casos de la base de datos, pero conservamos el diseño muestral. En el segundo escenario empleamos la opción ‘subset’ para filtrar a la subpoblación de interés.

#Regresión lineal recortando la base de datos
muestra_censal_recortada=subset(muestra_censal, b == 1)
ds_mc_con_muestra_recortada <- svydesign(id = ~UPM, strata = ~ESTRATO, weights = ~FACTOR, data = muestra_censal_recortada, nest = TRUE)

modelo_3 <- glm(as.numeric(ESCOACUM) ~ as.factor(SEXO) + as.factor(PERTE_INDIGENA), data=muestra_censal_recortada)
summary(modelo_3)

#Regresión lineal usando el comando subset
ds_mc5 <- svydesign(id = ~UPM, strata = ~ESTRATO, weights = ~FACTOR, data = muestra_censal, nest = TRUE)
ds_mc5_2<-subset(ds_mc5,b==1)

modelo_4 <- svyglm(as.numeric(ESCOACUM) ~ as.factor(SEXO) + as.factor(PERTE_INDIGENA), design = ds_mc5_2)
summary(modelo_4)

# Comparación de modelos
comparacion_rl <- data.frame(
  Estimate_3 = round(coef(modelo_3), 2),
  Estimate_4 = round(coef(modelo_4), 2)
)

signif_3 <- summary(modelo_3)$coefficients[,4] 
signif_4 <- summary(modelo_4)$coefficients[,4] 

estrella <- function(p.value){
  if(p.value < 0.001) return("***")
  else if(p.value < 0.01) return("**")
  else if(p.value < 0.05) return("*")
  else if(p.value < 0.1) return(".")
  else return("")
}

comparacion_2 <- data.frame(
  Coef_3 = round(coef(modelo_3), 2),
  Sig_3 = sapply(signif_3, estrella),
  Coef_4 = round(coef(modelo_4), 2),
  Sig_4 = sapply(signif_4, estrella)
)


Coef_3 Sig_3 Coef_4 Sig_4
(Intercept) 9.60 *** 9.09 ***
as.factor(SEXO)3 1.03 *** 0.97 ***
as.factor(PERTE_INDIGENA)3 0.65 . 1.37



6. Inferencia estadística

En la inferencia estadística el diseño de la muestra también influye en los resultados obtenidos. Declarar el diseño muestral asegura que la muestra sea representativa del universo de estudio, minimizando el sesgo y permitiendo inferencias válidas.

Veamos un ejemplo con el ingreso. Para validar si es igual a 0 realizamos una prueba de hipótesis t-test, donde:

  • La hipótesis nula (H0) es que el ingreso medio es igual a 0
  • La hipótesis alternativa (H1) que el ingreso medio es diferente de 0
ds_mc5 <- svydesign(id = ~UPM, strata = ~ESTRATO, weights = ~FACTOR, data = muestra_censal, nest = TRUE)
ds_mc5_2<-subset(ds_mc5,b==1)

svyttest(INGTRMEN~0, ds_mc5_2, na = FALSE)
## 
##  Design-based one-sample t-test
## 
## data:  INGTRMEN ~ 0
## t = 24.358, df = 485, p-value < 2.2e-16
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
##  4930.529 5795.781
## sample estimates:
##     mean 
## 5363.155


La prueba de chi-cuadrado se emplea frecuentemente para analizar la relación entre dos variables categóricas. No obstante, este método presupone una selección aleatoria de los datos, lo que no es adecuado para diseños de muestra complejos. Para estos casos, se recurre a la función svychisq, que ajusta la prueba de chi-cuadrado a las particularidades de las muestras complejas.

svychisq(~SEXO+AGUINALDO, ds_mc5_2, statistic="adjWald")
## 
##  Design-based Wald test of association
## 
## data:  svychisq(~SEXO + AGUINALDO, ds_mc5_2, statistic = "adjWald")
## F = 6.1602, ndf = 1, ddf = 486, p-value = 0.0134



Material extra

Te invito a visitar mi canal de YouTube Link, en el cual comparto videos sobre estadística multivariada y demografía. Si consideras que el contenido es de tu interés y utilidad, te agradecería mucho si decides suscribirte.