library(rio)
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.4.2
##
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
dataVotos = import("DataV.csv")
dataE = import("dataEDU.csv")
dataFC = import("Fc.csv")
# Combinar los dataframes uno por uno
temp1 = merge(dataE, dataFC, by='UBIGEO', all.x = T)
temp1 <- temp1 %>%
na.omit()
data_dep <- temp1 %>%
group_by(DEPARTAMENTO) %>%
summarise(across(where(is.numeric), sum, na.rm = TRUE), .groups = "drop")
## Warning: There was 1 warning in `summarise()`.
## ℹ In argument: `across(where(is.numeric), sum, na.rm = TRUE)`.
## ℹ In group 1: `DEPARTAMENTO = "AMAZONAS"`.
## Caused by warning:
## ! The `...` argument of `across()` is deprecated as of dplyr 1.1.0.
## Supply arguments directly to `.fns` through an anonymous function instead.
##
## # Previously
## across(a:b, mean, na.rm = TRUE)
##
## # Now
## across(a:b, \(x) mean(x, na.rm = TRUE))
data_dep <- data_dep[-19, ]
# Combinar los dataframes uno por uno
dataFinal = merge(data_dep, dataVotos, by='DEPARTAMENTO', all.x = T)
str(dataVotos)
## 'data.frame': 25 obs. of 5 variables:
## $ Castillo : chr "34 464" "110 620" "88 812" "256 224" ...
## $ Fujimori : chr "17 815" "67 394" "10 879" "40 216" ...
## $ Participación: chr "184 057" "613 850" "219 260" "902 243" ...
## $ Electores : chr "306 186" "886 265" "316 000" "1 145 268" ...
## $ DEPARTAMENTO : chr "AMAZONAS" "ANCASH" "APURIMAC" "AREQUIPA" ...
dataVotos <- dataVotos %>%
mutate(across(
.cols = -DEPARTAMENTO, # aplica a todas menos Departamento
.fns = ~ as.numeric(gsub(" ", "", .))
))
## Warning: There were 4 warnings in `mutate()`.
## The first warning was:
## ℹ In argument: `across(...)`.
## Caused by warning:
## ! NAs introducidos por coerción
## ℹ Run `dplyr::last_dplyr_warnings()` to see the 3 remaining warnings.
dataVotos$Electores[15] <- 8322644
dataVotos$Participación[15] <- 6206220
dataVotos$Fujimori[15] <- 754216
dataVotos$Castillo[15] <- 416743
data_dep$DEPARTAMENTO[data_dep$DEPARTAMENTO == "LIMA METROPOLITANA"] <- "LIMA"
data_unida <- data_dep %>%
group_by(DEPARTAMENTO) %>%
summarise(across(where(is.numeric), sum, na.rm = TRUE)) %>%
ungroup()
-Data final
# Combinar los dataframes uno por uno
dataFinal = merge(data_unida, dataVotos, by='DEPARTAMENTO', all.x = T)
Total de personas que no saben leer
Total de personas sin educación superior
Total de fallecidos durante la pandemia
library(modelsummary)
## Warning: package 'modelsummary' was built under R version 4.4.2
## `modelsummary` 2.0.0 now uses `tinytable` as its default table-drawing
## backend. Learn more at: https://vincentarelbundock.github.io/tinytable/
##
## Revert to `kableExtra` for one session:
##
## options(modelsummary_factory_default = 'kableExtra')
## options(modelsummary_factory_latex = 'kableExtra')
## options(modelsummary_factory_html = 'kableExtra')
##
## Silence this message forever:
##
## config_modelsummary(startup_message = FALSE)
h1 = formula(Castillo ~ total_no_lee + total_no_superior + total_fallecidos)
rp1 = glm(h1, data = dataFinal,
offset = log(Electores), #exposure
family = poisson(link = "log"))
summary(rp1)
##
## Call:
## glm(formula = h1, family = poisson(link = "log"), data = dataFinal,
## offset = log(Electores))
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -2.573e-01 3.336e-03 -77.12 <2e-16 ***
## total_no_lee 2.627e-03 7.280e-06 360.83 <2e-16 ***
## total_no_superior -1.032e-03 2.114e-06 -488.21 <2e-16 ***
## total_fallecidos 8.364e-05 1.938e-07 431.64 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for poisson family taken to be 1)
##
## Null deviance: 1375302 on 24 degrees of freedom
## Residual deviance: 554165 on 21 degrees of freedom
## AIC: 554499
##
## Number of Fisher Scoring iterations: 5
Exponenciamos para interpretar
cbind(exp(coef(rp1)),exp(confint(rp1)))
## Waiting for profiling to be done...
## 2.5 % 97.5 %
## (Intercept) 0.7731456 0.7681062 0.7782172
## total_no_lee 1.0026303 1.0026160 1.0026446
## total_no_superior 0.9989684 0.9989642 0.9989725
## total_fallecidos 1.0000836 1.0000833 1.0000840
Primeras conclusiones:
Todas la variables son significativas. total_no_lee (peronas analfabetas) Y total_fallecidos (personas que fallecieron a causa del Covid 19) poseen un relación positiva. Mientras que total_no_superior (personas que no cuentas con estudios superiores completos) es negativo, lo que indica que:
🔹 A mayor número de personas sin educación superior, menor es el número esperado de votos para Castillo, controlando por el total de electores (gracias al offset).
#Over y underdisperción: under → quasi poisson ; over → quasi y binomial negativa
library(magrittr)
library(kableExtra)
## Warning: package 'kableExtra' was built under R version 4.4.2
##
## Adjuntando el paquete: 'kableExtra'
## The following object is masked from 'package:dplyr':
##
## group_rows
overdispersion=AER::dispersiontest(rp1,alternative='greater')$ p.value<0.05
underdispersion=AER::dispersiontest(rp1,alternative='less')$ p.value<0.05
# tabla
testResult=as.data.frame(rbind(overdispersion,underdispersion))
names(testResult)='Es probable?'
testResult%>%kable(caption = "Test de Equidispersión")%>%kableExtra::kable_styling()
| Es probable? | |
|---|---|
| overdispersion | TRUE |
| underdispersion | FALSE |
# Regresión Quasipoisson
rqp = glm(h1, data = dataFinal,
offset=log(Electores),
family = quasipoisson(link = "log"))
summary(rqp)
##
## Call:
## glm(formula = h1, family = quasipoisson(link = "log"), data = dataFinal,
## offset = log(Electores))
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -2.573e-01 5.307e-01 -0.485 0.63280
## total_no_lee 2.627e-03 1.158e-03 2.269 0.03396 *
## total_no_superior -1.032e-03 3.363e-04 -3.069 0.00582 **
## total_fallecidos 8.364e-05 3.082e-05 2.714 0.01301 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for quasipoisson family taken to be 25300.24)
##
## Null deviance: 1375302 on 24 degrees of freedom
## Residual deviance: 554165 on 21 degrees of freedom
## AIC: NA
##
## Number of Fisher Scoring iterations: 5
Entonces..
Todas las variables son significativas, pero total_no_superior (personas que no saben leer) es la variable con más significancia y negativa.
#Regresión Binomial Negativa:
# bin
h1off=formula(Castillo ~ total_no_lee + total_no_superior + total_fallecidos + offset(log(Electores)))
rbn=MASS::glm.nb(h1off,data=dataFinal)
summary(rbn)
##
## Call:
## MASS::glm.nb(formula = h1off, data = dataFinal, init.theta = 3.630886751,
## link = log)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -2.426e-01 4.945e-01 -0.491 0.62378
## total_no_lee 1.488e-03 1.120e-03 1.328 0.18404
## total_no_superior -8.227e-04 3.104e-04 -2.650 0.00805 **
## total_fallecidos 6.807e-05 2.843e-05 2.395 0.01664 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for Negative Binomial(3.6309) family taken to be 1)
##
## Null deviance: 40.128 on 24 degrees of freedom
## Residual deviance: 26.139 on 21 degrees of freedom
## AIC: 610.36
##
## Number of Fisher Scoring iterations: 1
##
##
## Theta: 3.631
## Std. Err.: 0.983
##
## 2 x log-likelihood: -600.357
👉 Para analizar los factores asociados al número de votos recibidos por Pedro Castillo en las elecciones generales de 2021, se estimaron tres modelos de regresión para datos de conteo: Poisson, Quasipoisson y Binomial Negativa. La variable dependiente fue el número de votos por Castillo a nivel departamental, y se incluyó un offset del logaritmo del total de electores para controlar por el tamaño del padrón.
En los tres modelos, la variable total_no_superior resultó ser la más significativa y consistente, mostrando una relación negativa con el número de votos por Castillo.
Correteaste la regresión Poisson pero usando las variables positivas:
total_lee = personas que saben leer
total_superior = personas con educación superior
total_fallecidos = fallecidos por COVID (igual que antes)
h2 = formula(Castillo ~ total_lee + total_superior + total_fallecidos)
rp2 = glm(h2, data = dataFinal,
offset = log(Electores), #exposure
family = poisson(link = "log"))
summary(rp2)
##
## Call:
## glm(formula = h2, family = poisson(link = "log"), data = dataFinal,
## offset = log(Electores))
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -9.157e-01 2.703e-03 -338.8 <2e-16 ***
## total_lee -1.065e-03 3.056e-06 -348.6 <2e-16 ***
## total_superior -5.970e-04 5.199e-06 -114.8 <2e-16 ***
## total_fallecidos 2.064e-05 1.638e-07 126.0 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for poisson family taken to be 1)
##
## Null deviance: 1375302 on 24 degrees of freedom
## Residual deviance: 689847 on 21 degrees of freedom
## AIC: 690181
##
## Number of Fisher Scoring iterations: 5
Que el voto por Castillo está negativamente relacionado con el nivel educativo,
Entendiendo el contraste: en relación con la variable de educación superior
El efecto de educación superior podría no ser lineal o simplemente tener un comportamiento más complejo. Quizá hay una variable intermedia como educación técnica, que sí fue incluida en esta variable.
#Over y underdisperción: under → quasi poisson ; over → quasi y binomial negativa
overdispersion=AER::dispersiontest(rp2,alternative='greater')$ p.value<0.05
underdispersion=AER::dispersiontest(rp2,alternative='less')$ p.value<0.05
# tabla
testResult=as.data.frame(rbind(overdispersion,underdispersion))
names(testResult)='Es probable?'
testResult%>%kable(caption = "Test de Equidispersión")%>%kableExtra::kable_styling()
| Es probable? | |
|---|---|
| overdispersion | TRUE |
| underdispersion | FALSE |
# Regresión Quasipoisson
rqp2 = glm(h2, data = dataFinal,
offset=log(Electores),
family = quasipoisson(link = "log"))
summary(rqp2)
##
## Call:
## glm(formula = h2, family = quasipoisson(link = "log"), data = dataFinal,
## offset = log(Electores))
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -9.157e-01 4.591e-01 -1.995 0.0592 .
## total_lee -1.065e-03 5.192e-04 -2.052 0.0528 .
## total_superior -5.970e-04 8.831e-04 -0.676 0.5064
## total_fallecidos 2.064e-05 2.782e-05 0.742 0.4665
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for quasipoisson family taken to be 28854.06)
##
## Null deviance: 1375302 on 24 degrees of freedom
## Residual deviance: 689847 on 21 degrees of freedom
## AIC: NA
##
## Number of Fisher Scoring iterations: 5
En este caso las variables total_lee y total_superior tiene un sentido negativo y significativo, pero no tanto como en la primera regresión (Poisson 1). Asimismo, total_fallecidos mantiene su sentido positivo.
#Regresión Binomial Negativa:
# bin
h2off=formula(Castillo ~ total_lee + total_superior + total_fallecidos + offset(log(Electores)))
rbn2=MASS::glm.nb(h2off,data=dataFinal)
summary(rbn2)
##
## Call:
## MASS::glm.nb(formula = h2off, data = dataFinal, init.theta = 3.2656611,
## link = log)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -6.807e-01 4.986e-01 -1.365 0.1722
## total_lee -1.430e-03 5.566e-04 -2.569 0.0102 *
## total_superior -6.469e-04 8.891e-04 -0.728 0.4669
## total_fallecidos 2.688e-05 2.974e-05 0.904 0.3660
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for Negative Binomial(3.2657) family taken to be 1)
##
## Null deviance: 36.092 on 24 degrees of freedom
## Residual deviance: 26.264 on 21 degrees of freedom
## AIC: 613.26
##
## Number of Fisher Scoring iterations: 1
##
##
## Theta: 3.266
## Std. Err.: 0.881
##
## 2 x log-likelihood: -603.260
En la regresión binomial negativa se puede observar, el mismo patron las variables total_lee y total_superior tiene un sentido negativo, pero la unica variable significativa es la de personas que saben leer.
Construcción de variables independientes (VI)
Para analizar la relación entre el nivel educativo y el comportamiento electoral, se construyeron variables agregadas a partir de los registros individuales de la Encuesta Nacional de Hogares (ENAHO). Las variables clave utilizadas fueron:
A partir de estas variables se generaron las siguientes agrupaciones:
1. Educación superior
Se construyó la variable total_superior, que agrupa a todas
las personas que han culminado al menos un nivel de educación superior.
Esto incluye los siguientes códigos de la variable P301A:
- 8: Superior no universitaria completa
- 10: Superior universitaria completa
- 11: Maestría o Doctorado
2. Sin educación superior
La variable total_no_superior incluye a todas las personas
que no tienen estudios superiores completos. Se agruparon los siguientes
códigos de P301A:
- 1 a 7 y 9: desde sin nivel
hasta educación superior incompleta (no universitaria o
universitaria)
3. Sabe leer y escribir
La variable total_lee corresponde a todas las personas que
respondieron “Sí” (código 1) en la variable P302.
4. No sabe leer y escribir
La variable total_no_lee incluye a quienes respondieron
“No” (código 2) en la variable P302.
Los valores perdidos (9) fueron tratados como casos
faltantes y no considerados en el análisis.
Finalmente, estas variables fueron agregadas a nivel departamental para que pudieran ser usadas como predictores en los modelos de regresión.
Fuentes:
Educación ENAHO: https://proyectos.inei.gob.pe/microdatos/
Votos wikipedia: https://es.wikipedia.org/wiki/Elecciones_generales_de_Per%C3%BA_de_2021