Explorando los resultados de las PASO 2021

Inicio

El presente documento electrónico es un ejercicio abierto de extracción, sistematización y visualización de los resultados del recuento provisional de las Elecciones Primarias, Abiertas, Simultáneas y Obligatorias en Argentina (PASO 2021).

Tanto la presentación de los datos como la síntesis del abordaje parten de una elaboración original, especialmente desarrollada para el encuentro Cómo empezar? de R-Ladies y NIS. El mismo puede verse completo aquí, y el ejercicio allí presentado puede descargarse de github.

La Consulta

Si nuestra intensión es consultar los datos de las PASO 2021 debemos acceder al portal del Estado Nacional donde se encuentra publicado el recuento provisorio: https://www.argentina.gob.ar/elecciones/resultados-del-recuento-provisional-de-las-elecciones-paso. Aquí encontraremos los resultados de las elecciones por provincia (y sección para el caso de Buenos Aires). En esta oportunidad vamos poner nuestros ojos en un caso súper local, queremos conocer cuáles fueron los resultados de las elecciones PASO en mi ciudad: Lanús, Provincia de Buenos Aires, correspondiente a la tercera sección electoral.

Es importante destacar que a los fines expositivos de este documento no vamos a descargar los datos localmente, sino que los consultaremos de manera remota conectándonos mediante el siguiente enlace: https://argentina.gob.ar/sites/default/files/buenos_aires_tercera.zip . La recomendación, para un correcto trabajo de análisis es trabajar con los datos descargadas previamente.

Hands on Lanús

Primero y principal vamos a levantar las librerías que utilizaremos para nuestra consulta:

library(data.table) # nos interesa fread para levantar el CSV
library(tidyverse) #un clásico
library(stringr) # para limpiar y acomodar el dataframe
library(ggplot2) # (L)
library(fst)
library(widgetframe)
library(artyfarty) # para customizar los gglots
library(sf) #para trabajar con coordenadas
library(leaflet) # para crear mapas

Como lo planteáramos anteriormente, descargaremos el set de datos de los votos correspondiente a la tercera sección electoral de la provincia de Buenos Aires. Lo que observaremos inicialmente es que el enlace nos remite a un archivo comprimido zip. Resolvemos la descarga con el siguiente código:

activity_url <- "https://argentina.gob.ar/sites/default/files/buenos_aires_tercera.zip" 
#Recordemos que este era el link que nos interesaba
temp <- tempfile()
download.file(activity_url, temp)
unzip(temp, "Buenos Aires_Tercera.csv") #lo descarga en nuestro proyecto
ba_tercera <- fread("Buenos Aires_Tercera.csv", sep=";")
unlink(temp)

Al checkear nuestros datos nos encontraremos con más de un millón de observaciones y 19 variables correspondiente a los resultados de las PASO por municipio (de la tercera sección), lista en pugna, agrupaciones y escuelas donde votaron lxs ciudadanxs.

Ahora que verificamos que nuestros datos iniciales están ok, haremos una síntesis que de cuenta del panorama de votos para la categoría concejales en Lanús. Nos interesa generar un cuadro que recoja los votos totales y porcentuales por agrupación (partidos) y lista (subcategorías dentro de las agrupaciones), con ambos registros podemos aproximarnos un panorama descriptivo de las elecciones en el municipio. Para ello, una estrategia, de muchas posibles, es armar dos cuadros que posteriormente uniremos para obtener los datos tal como los queremos.

lanus_listas <- ba_tercera%>%
filter(Cargo=="CONCEJALES") %>% #filtra concejales
filter(Seccion=="Lanús") %>%  #filtra para lanus
select(Agrupacion, lista, tipoVoto, votos) %>% #seleccion de variables
mutate(tipo_voto = case_when(tipoVoto %in% "blancos" ~ "blancos",
                      tipoVoto %in% c("nulos", "recurridos",
                      "impugnados", "comando") ~ "nulos", 
                      tipoVoto %in% "positivo" ~ "positivo"))%>% 
group_by(Agrupacion, lista, tipo_voto) %>%
summarise(votos_lista=sum(votos)) %>% #dato de votos por lista 
mutate(across(where(is.character), 
str_remove_all, pattern = fixed("positivo")))  

Qué Pasó?

Acomodemos la tabla para organizar los datos por lista y agrupación. Graficaremos al final un posible output.

lanus_listas$listas <- paste(lanus_listas$lista, 
                             lanus_listas$tipo_voto)
lanus_listas$agrupaciones <- paste(lanus_listas$Agrupacion, 
                                   lanus_listas$tipo_voto)
#N y % votos por agrupación
lanus_agrupaciones <- lanus_listas%>%
group_by(agrupaciones) %>% 
summarise(votos_agrupacion=sum(votos_lista)) %>% 
mutate(totales=sum(votos_agrupacion),
         porc_agrupacion=1e2*votos_agrupacion/totales)
# complementa % votos por lista y arma el df final
lanus_concejales <- lanus_listas %>% 
left_join(lanus_agrupaciones, by="agrupaciones") %>%
mutate(porc_lista=1e2*votos_lista/votos_agrupacion) %>%
ungroup() %>% 
select(agrupaciones, listas, votos_agrupacion,
         votos_lista, porc_agrupacion, porc_lista)

lanus_agrupaciones%>%
select(agrupaciones,votos_agrupacion, porc_agrupacion) %>%
mutate_if(is.numeric, round, digits=1)%>%
arrange(desc(porc_agrupacion)) %>%
rename(Agrupaciones=agrupaciones,
         `N votos`=votos_agrupacion,
         `% de votos`=porc_agrupacion) %>% 
knitr::kable()
Agrupaciones N votos % de votos
FRENTE DE TODOS 97929 38.3
JUNTOS 94807 37.1
FRENTE DE IZQUIERDA Y DE TRABAJADORES - UNIDAD 12914 5.1
blancos 12674 5.0
AVANZA LIBERTAD 12205 4.8
FRENTE VAMOS CON VOS 8571 3.4
nulos 4078 1.6
UNION CELESTE Y BLANCO 2655 1.0
MOVIMIENTO AL SOCIALISMO 2012 0.8
REPUBLICANO FEDERAL 1766 0.7
UNION POR TODOS 1525 0.6
FRENTE PATRIOTA 1121 0.4
FEDERAL 825 0.3
HUMANISTA 717 0.3
TODOS POR BUENOS AIRES 783 0.3
CONSERVADOR POPULAR 433 0.2
RENOVADOR FEDERAL 470 0.2

Lo logramos! Para finalizar visualizaremos nuestro trabajo destacando la performance electoral de las fuerzas políticas más votadas en el municipio. Primero imprimiremos el porcentual de votos por agrupación:

p <- lanus_concejales%>%
select(agrupaciones, porc_agrupacion) %>% 
distinct()%>%
filter(porc_agrupacion>1) %>% #sacamos a las fuerzas de 1% o menos
arrange(porc_agrupacion) %>% 
mutate(agrupaciones= fct_recode(agrupaciones,
"FIT"= "FRENTE DE IZQUIERDA Y DE TRABAJADORES - UNIDAD "))%>%
mutate_if(is.numeric, round, digits=1)%>%
ggplot(aes(x = reorder(agrupaciones, +porc_agrupacion, sum), 
y = porc_agrupacion, fill = agrupaciones)) +
geom_bar(stat = "identity")+
coord_flip()+
geom_text(aes(label=porc_agrupacion), 
size = 2, lineheight=.7, 
position = position_stack(vjust = 0.4))+
ggtitle("PASO 2021 Lanús: Porcentaje de votos por agrupación política para la categoría concejal.") +
labs(x= "Agrupación",
y= "% votos por agrupación",
fill = "Agrupaciones",
caption = "Fuente: datos abiertos de la Dirección Nacional Electoral.")+
theme(plot.title = element_text(hjust = 0.5, size = 9, 
lineheight=.7, face="bold",
margin=margin(15,15,15,15)),    
axis.text.x = element_text(angle = 45, size = 5),
axis.title.x = element_text(size = 7),
axis.title.y = element_text(size = 7),
axis.text.y = element_text(size = 7),
plot.caption = element_text(hjust = 0, face = "italic", size = 6),
legend.title = element_text(color = "black", size = 6),
legend.text = element_text(color = "black", size = 5),
legend.position="right")
print(p)

Y luego consultaremos el porcentaje de votos por lista (interna), en este caso mejorando el aspecto visual de nuestro nuestro plot:

p <- lanus_concejales%>%
filter(votos_agrupacion>12900) %>% 
mutate(agrupaciones= fct_recode(agrupaciones,
"FIT"= "FRENTE DE IZQUIERDA Y DE TRABAJADORES - UNIDAD "))%>%
mutate_if(is.numeric, round, digits=1)%>%
ggplot(aes(x = reorder(listas, +porc_lista, sum), 
y = porc_lista, fill = agrupaciones)) +
geom_bar(stat = "identity")+
geom_text(aes(label=porc_lista), 
position=position_dodge(width=0.1), vjust=-0.25,
size = 2, lineheight=.7, margin=margin(-15,0,0,0))+
ggtitle("PASO 2021 Lanús: Porcentaje de votos a concejal por lista, según agrupación política") +
scale_fill_manual(values = pal("d3js"))+
labs(x= "Listas",
y= "% Votos por lista.",
fill = "Agrupaciones",
caption = "Fuente: datos abiertos de la Dirección Nacional Electoral.")+
theme(plot.title = element_text(hjust = 0.5, size = 9, 
lineheight=.7, face="bold",
margin=margin(15,15,15,15)),    
axis.text.x = element_text(angle = 45, size = 5,
margin=margin(-15,-15,-15,-15)),
axis.title.x = element_text(size = 7, 
margin=margin(-15,-15,-15,-15)),
axis.title.y = element_text(size = 7),
axis.text.y = element_text(size = 7),
plot.background=element_rect(fill = "#fefdf6"),
panel.background = element_rect(fill = '#F0EDE3'),
panel.grid.major = element_line(colour = "#b4d9cf"),
strip.background = element_rect(fill="#b4d9cf"),
plot.caption = element_text(hjust = 0, face = "italic", size = 6,
margin=margin(20,20,20,20)),
legend.title = element_text(color = "black", size = 6),
legend.text = element_text(color = "black", size = 5),
legend.position="right")+
facet_wrap(~agrupaciones, scales = "free", ncol = 3)

print(p)

Adelanto: geolocalización del voto por escuela

Al momento hemos operado con los datos a escala municipal, es decir que para generar una primera aproximación con nuestra información hemos resumido los principales eventos para el conjunto de Lanús en tanto unidad de análisis.

Entonces puesto que con millones de datos también se pueden observar pequeñas historias, para concluir, generaremos datos para una escuela del municipio elegida aletoriamente. Volvamos a nuestros datos y seleccionemos una escuela al azar para explorar:

lanus <- ba_tercera%>%
filter(Seccion=="Lanús")
set.seed(150)
escuela<-sample(lanus$Establecimiento, 1)
escuela
## [1] "ESCUELA EP N°46/ES N°40"

El resultado aleatorio nos invita a hacer zoom en la situación del establecimiento: “ESCUELA EP N°46/ES N°40”..

Generamos nuestro set de datos:

lanus_escuela<-lanus%>%
filter(Establecimiento==escuela)%>%
filter(Cargo=="CONCEJALES")%>%
select(Agrupacion, tipoVoto, votos) %>% #seleccion de variables
mutate(tipo_voto = case_when(tipoVoto %in% "blancos" ~ "blancos",
                               tipoVoto %in% c("nulos", "recurridos",
                                               "impugnados", "comando") ~ "nulos", 
                               tipoVoto %in% "positivo" ~ "positivo"))%>% 
group_by(Agrupacion, tipo_voto) %>%
summarise(votos_agrupacion=sum(votos)) %>% #dato de votos por lista 
mutate(across(where(is.character), 
str_remove_all, pattern = fixed("positivo")))  
lanus_escuela$agrupaciones <- paste(lanus_escuela$Agrupacion, 
                                    lanus_escuela$tipo_voto)
lanus_escuela<-lanus_escuela%>%
group_by(agrupaciones) %>% 
summarise(votos_agrupacion=sum(votos_agrupacion)) %>% 
mutate(totales=sum(votos_agrupacion),
porc_agrupacion=1e2*votos_agrupacion/totales)

Grafiquemos los resultados electorales para esta escuela en particular, aplicando lo que estuvimos viendo anteriormente.

p <- lanus_escuela%>%
select(agrupaciones, porc_agrupacion) %>% 
distinct()%>%
filter(porc_agrupacion>1) %>% #sacamos a las fuerzas de 1% o menos
arrange(porc_agrupacion) %>% 
mutate(agrupaciones= fct_recode(agrupaciones,
"FIT"= "FRENTE DE IZQUIERDA Y DE TRABAJADORES - UNIDAD "))%>%
mutate_if(is.numeric, round, digits=1)%>%
ggplot(aes(x = reorder(agrupaciones, +porc_agrupacion, sum), 
y = porc_agrupacion, fill = agrupaciones)) +
geom_bar(stat = "identity")+
coord_flip()+
geom_text(aes(label=porc_agrupacion), 
size = 2, lineheight=.7, 
position = position_stack(vjust = 0.4))+
labs(title="PASO 2021 Lanús: Porcentaje de votos por agrupación política para la categoría concejal.",
subtitle="Datos para ESCUELA EP N°46/ES N°40 (Montechingolo)",
x= "Agrupación",
y= "% votos por agrupación",
fill = "Agrupaciones",
caption = "Fuente: datos abiertos de la Dirección Nacional Electoral.")+
scale_fill_manual(values = pal("d3js"))+
labs(x= "Agrupaciones",
y= "% Votos",
fill = "Agrupaciones",
caption = "Fuente: datos abiertos de la Dirección Nacional Electoral.")+
theme(plot.title = element_text(hjust = 0.5, size = 10, 
                                  lineheight=.7, face="bold"),
        plot.subtitle = element_text(hjust = 0.5, size = 9, 
                                  lineheight=.7, face="italic"),
        axis.text.x = element_text(angle = 45, size = 5),
        axis.title.x = element_text(size = 7),
        axis.title.y = element_text(size = 7),
        axis.text.y = element_text(size = 7),
        plot.caption = element_text(hjust = 0, face = "italic", size = 6),
        legend.title = element_text(color = "black", size = 6),
        legend.text = element_text(color = "black", size = 5),
        legend.position="right")
print(p)

Finalmente el adelanto de lo que viene; un ejercicio de geo-referenciamiento que nos devuelve la agrupación que virtualmente ganaría, por escuela, si se computaran los votos de las paso por fuerza política y no por lista. La propuesta en este caso es generar para las elecciones generales un mapa de similares características con los resultados definitivos. Al momento matcheé el 60% de los establecimientos tomando como referencia el padrón de escuelas del ministerio de educación, pero esta ya es otra historia…

Apreciaciones finales

El presente ejercicio de extracción de datos nos ha permitido conocer con nuestros propios recursos la realidad electoral específica de un municipio de la provincia de Buenos Aires. Repasando el proceso nos hemos conectado directamente, sin intermediarios, a la fuente de interés; el recuento provisional de votos PASO 2021 para producir nuestra propia información y abrirla a la comunidad.

Verificamos que el caso electoral de Lanús, como el de otros municipios, puede ser ágilmente asequible por la vía de los datos, y a través de ellos podemos llegar a dar con situaciones moleculares como lo es el voto a una determinada fuerza política en un barrio o escuela.

Hasta aquí la exposición del día! invito a que sigan ordenando los datos por las distintas regiones y categorías de la elección, prestando atención, por ejemplo, a la categoría de diputadxs nacionales, provinciales, como así también a la posibilidad de seguir filtrando los resultados por provincia, municipio, o escuela.

Комментарии