library(tidyverse) # librería para análisis general
library(sf) # librería para datos geográficos
library(ggmap) # librería para mapas base
library(leaflet) # para mapas interactivos
library(GGally) # pairplots
Elecciones G2023 & cercanía con elementos clave
Análisis sobre las elecciones generales de 2023 en Provincia de Buenos Aires
Elementos clave: educación, salud, ferrocarriles y complejos industriales
Este análisis se realiza en el contexto del módulo “Ciencia de Datos II” del curso de FLACSO “Big Data e Inteligencia Territorial”. La idea es explorar los resultados de las elecciones generales del año 2023 en relación con distintos elementos que entendemos importantes a la hora de evaluar una gestión gubernamental: equipamiento público (establecimientos educativos, establecimientos de salud, estaciones de ferrocarriles) y sumamos agrupamientos industriales como un proxy de empleo industrial (que suele ser de mayor calidad que otros empleos más comunes). Estos cuatro datasets geográficos fueron obtenidos del catálogo de datos abiertos de la Provincia de Buenos Aires: https://catalogo.datos.gba.gob.ar
En particular, las preguntas que orientan brevísimo trabajo son: ¿Cómo se distribuyen geográficamente los mencionados elementos clave? ¿Cómo es la relación entre la presencia de distintos elementos clave y los resultados electorales de las elecciones generales 2023?
Comenzamos cargando las librerías que vamos a usar.
Vamos a cargar las bases de datos y transformarlas en archivos geográficos. Los objetos que comiencen con ec_ serán los elementos clave que se mencionaron en la introducción. Cargamos en el siguiente orden: establecimientos educativos, establecimientos de salud públicos, estaciones de ferrocarril y agrupamientos industriales.
<- 'bases/establecimientos-educativos-12082024.geojson'
path <- st_read(path) %>% mutate(origen="est. educativos") ec_edu
Reading layer `edu' from data source
`C:\Users\Usuario\Documents\personal\curso big data e inteligencia territorial\analisis G2023\bases\establecimientos-educativos-12082024.geojson'
using driver `GeoJSON'
Simple feature collection with 21626 features and 54 fields
Geometry type: POINT
Dimension: XY
Bounding box: xmin: -63.38269 ymin: -40.8115 xmax: -56.67471 ymax: -33.29664
Geodetic CRS: WGS 84
<- 'bases/Establecimientos_salud_publicos_alta_al20220721.geojson'
path <- st_read(path)%>% mutate(origen="est. de salud") ec_sal
Reading layer `Establecimientos_salud_publicos_alta_al20220721' from data source `C:\Users\Usuario\Documents\personal\curso big data e inteligencia territorial\analisis G2023\bases\Establecimientos_salud_publicos_alta_al20220721.geojson'
using driver `GeoJSON'
Simple feature collection with 2840 features and 22 fields
Geometry type: POINT
Dimension: XY
Bounding box: xmin: -63.3788 ymin: -40.81011 xmax: -56.67763 ymax: -33.29881
Geodetic CRS: WGS 84
<- 'bases/estaciones-ferrocarril-provincia.geojson'
path <- st_read(path)%>% mutate(origen="estaciones ferrocarril") ec_fer
Reading layer `estaciones-ferrocarril-provincia (1)' from data source
`C:\Users\Usuario\Documents\personal\curso big data e inteligencia territorial\analisis G2023\bases\estaciones-ferrocarril-provincia.geojson'
using driver `GeoJSON'
Simple feature collection with 1028 features and 8 fields
Geometry type: POINT
Dimension: XY
Bounding box: xmin: -63.38197 ymin: -40.79153 xmax: -56.90283 ymax: -33.34428
Geodetic CRS: WGS 84
<- 'bases/agrupamientos-industriales.xlsx'
path <- readxl::read_excel(path) %>%
ec_ind mutate(origen="agrup. industriales")
Explorando las bases
Hagamos un pequeño análisis de forma de las bases cargadas.
%>% dim() ec_edu
[1] 21626 56
%>% dim() ec_sal
[1] 2840 24
%>% dim() ec_fer
[1] 1028 10
%>% dim() ec_ind
[1] 83 31
table(ec_edu$nivel)
Ciclo de Iniciaci�n
57
Ciclo Medio
52
Cursos y Talleres
93
Educaci�n F�sica (C.E.F.)
198
Formaci�n Integral
564
Formaci�n Profesional
664
Nivel Inicial
6131
Nivel Medio
583
Nivel Primario
7481
Nivel Secundario
4743
Nivel Superior (**)
647
Plan Fines (Trayectos y Deudores)
163
Psicolog�a Comunitaria y Pedagog�a (C.E.C)
188
Residencia Laboral,Pasantias, Art�stica
62
%>% class() ec_edu
[1] "sf" "data.frame"
%>% class() ec_sal
[1] "sf" "data.frame"
%>% class() ec_fer
[1] "sf" "data.frame"
%>% class() ec_ind
[1] "tbl_df" "tbl" "data.frame"
%>% names() ec_edu
[1] "row_number" "idserv" "clave" "cueanexo" "nombre"
[6] "id_modalid" "modalidad" "id_nivel" "nivel" "id_periodo"
[11] "periodo" "calle" "nro" "calle_late" "calle_lat0"
[16] "id_localid" "localidad" "codigo_pos" "id_distrit" "distrito"
[21] "region" "region_edu" "categoria" "depend_fun" "caracteris"
[26] "nro_telefo" "rpv" "email" "desfavorab" "subvencion"
[31] "id_ubicaci" "ubicacion" "id_sector" "sector" "id_depende"
[36] "dependenci" "id_tipo_or" "tipo_organ" "matricula" "varones"
[41] "mujeres" "secciones" "turnos" "capa" "area"
[46] "seccion_el" "sede_axo_e" "esc_sede" "cue" "anexo"
[51] "nro_escuel" "latitud" "longitud" "cui" "geometry"
[56] "origen"
%>% names() ec_sal
[1] "id" "lat" "long" "fna" "gna" "nam"
[7] "sag" "cpd" "cnr" "cde" "nde" "nba"
[13] "tes" "cat" "dom" "tel" "sse" "nrs"
[19] "cp1" "nor" "mod" "mai" "geometry" "origen"
%>% names() ec_fer
[1] "gid" "entidad" "fna" "gna" "nam" "fun"
[7] "fdc" "sag" "geometry" "origen"
%>% names() ec_ind
[1] "municipio_id"
[2] "municipio_nombre"
[3] "localidad"
[4] "nombre_agrupamiento_promotor"
[5] "tipologia"
[6] "iniciativa"
[7] "tipo_segun_origen"
[8] "numero_decreto"
[9] "numero_decreto_de_ampliacion"
[10] "ubicacion"
[11] "latitud"
[12] "longitud"
[13] "nombre_de_contacto"
[14] "institucion"
[15] "telefono"
[16] "mail_1"
[17] "mail_2"
[18] "superficie_hectareas"
[19] "cantidad_lotes_parcelas"
[20] "lotes_parcelas_disponibles"
[21] "reglamento_interno"
[22] "area_de_reserva"
[23] "infraestructura_basica"
[24] "servicio_ adicionales"
[25] "centro_de_capacitación_en_el_agrupamiento"
[26] "vinculación_con_un_centro_de_formación_externo"
[27] "numero_empresas"
[28] "numero_empleados_estimado"
[29] "seccion_electoral"
[30] "interior_conurbano"
[31] "origen"
table(ec_fer$gna)
Apeadero Desvío Divisadero Empalme Estación Parada
5 7 1 4 1002 9
%>% summary() ec_edu
row_number idserv clave cueanexo
Min. : 1 Min. : 1 Length:21626 Length:21626
1st Qu.: 5407 1st Qu.: 5687 Class :character Class :character
Median :10814 Median : 11634 Mode :character Mode :character
Mean :10814 Mean : 17992
3rd Qu.:16220 3rd Qu.: 19534
Max. :21626 Max. :103421
nombre id_modalid modalidad id_nivel
Length:21626 Min. :1.000 Length:21626 Min. : 1.000
Class :character 1st Qu.:1.000 Class :character 1st Qu.: 1.000
Mode :character Median :1.000 Mode :character Median : 2.000
Mean :1.561 Mean : 2.871
3rd Qu.:2.000 3rd Qu.: 3.000
Max. :7.000 Max. :17.000
nivel id_periodo periodo calle
Length:21626 Min. : 0.0 Length:21626 Length:21626
Class :character 1st Qu.:106.0 Class :character Class :character
Mode :character Median :106.0 Mode :character Mode :character
Mean :105.4
3rd Qu.:106.0
Max. :106.0
nro calle_late calle_lat0 id_localid
Length:21626 Length:21626 Length:21626 Min. : 2.0
Class :character Class :character Class :character 1st Qu.: 311.0
Mode :character Mode :character Mode :character Median : 541.0
Mean : 787.9
3rd Qu.: 855.0
Max. :11114.0
localidad codigo_pos id_distrit distrito
Length:21626 Length:21626 Length:21626 Length:21626
Class :character Class :character Class :character Class :character
Mode :character Mode :character Mode :character Mode :character
region region_edu categoria depend_fun
Length:21626 Length:21626 Length:21626 Length:21626
Class :character Class :character Class :character Class :character
Mode :character Mode :character Mode :character Mode :character
caracteris nro_telefo rpv email
Length:21626 Length:21626 Length:21626 Length:21626
Class :character Class :character Class :character Class :character
Mode :character Mode :character Mode :character Mode :character
desfavorab subvencion id_ubicaci ubicacion
Min. :0.0000 Length:21626 Min. :-1.00 Length:21626
1st Qu.:0.0000 Class :character 1st Qu.: 1.00 Class :character
Median :0.0000 Mode :character Median : 1.00 Mode :character
Mean :0.5271 Mean : 1.34
3rd Qu.:1.0000 3rd Qu.: 1.00
Max. :5.0000 Max. : 4.00
id_sector sector id_depende dependenci
Min. :5.000 Length:21626 Length:21626 Length:21626
1st Qu.:5.000 Class :character Class :character Class :character
Median :6.000 Mode :character Mode :character Mode :character
Mean :5.716
3rd Qu.:6.000
Max. :6.000
id_tipo_or tipo_organ matricula varones
Length:21626 Length:21626 Min. : 0.0 Min. : 0.0
Class :character Class :character 1st Qu.: 56.0 1st Qu.: 27.0
Mode :character Mode :character Median : 154.0 Median : 75.0
Mean : 231.2 Mean : 113.5
3rd Qu.: 323.0 3rd Qu.: 157.0
Max. :7248.0 Max. :2511.0
mujeres secciones turnos capa
Min. : 0.0 Min. : 0.000 Length:21626 Min. : 1.000
1st Qu.: 26.0 1st Qu.: 3.000 Class :character 1st Qu.: 1.000
Median : 76.0 Median : 7.000 Mode :character Median : 2.000
Mean : 117.7 Mean : 9.643 Mean : 3.912
3rd Qu.: 162.0 3rd Qu.: 12.000 3rd Qu.: 5.000
Max. :6082.0 Max. :359.000 Max. :18.000
area seccion_el sede_axo_e esc_sede
Length:21626 Min. :1.000 Length:21626 Length:21626
Class :character 1st Qu.:1.000 Class :character Class :character
Mode :character Median :3.000 Mode :character Mode :character
Mean :3.319
3rd Qu.:5.000
Max. :8.000
cue anexo nro_escuel latitud
Min. :600001 Min. : 0.00000 Length:21626 Min. :-40.81
1st Qu.:605797 1st Qu.: 0.00000 Class :character 1st Qu.:-35.58
Median :611014 Median : 0.00000 Mode :character Median :-34.76
Mean :611941 Mean : 0.07838 Mean :-35.35
3rd Qu.:618114 3rd Qu.: 0.00000 3rd Qu.:-34.58
Max. :690035 Max. :18.00000 Max. :-33.30
longitud cui geometry origen
Min. :-63.38 Length:21626 POINT :21626 Length:21626
1st Qu.:-59.51 Class :character epsg:4326 : 0 Class :character
Median :-58.64 Mode :character +proj=long...: 0 Mode :character
Mean :-59.14
3rd Qu.:-58.38
Max. :-56.67
%>% summary() ec_sal
id lat long fna
Min. : 1 Min. :-40.81 Min. :-63.38 Length:2840
1st Qu.: 694 1st Qu.:-36.21 1st Qu.:-60.22 Class :character
Median :1390 Median :-34.80 Median :-58.76 Mode :character
Mean :1488 Mean :-35.47 Mean :-59.37
3rd Qu.:2086 3rd Qu.:-34.58 3rd Qu.:-58.39
Max. :6377 Max. :-33.30 Max. :-56.68
NA's :103
gna nam sag cpd
Length:2840 Length:2840 Length:2840 Length:2840
Class :character Class :character Class :character Class :character
Mode :character Mode :character Mode :character Mode :character
cnr cde nde nba
Min. :1.006e+13 Length:2840 Length:2840 Length:2840
1st Qu.:5.006e+13 Class :character Class :character Class :character
Median :5.006e+13 Mode :character Mode :character Mode :character
Mean :4.387e+13
3rd Qu.:5.007e+13
Max. :8.006e+13
NA's :234
tes cat dom tel
Length:2840 Length:2840 Length:2840 Length:2840
Class :character Class :character Class :character Class :character
Mode :character Mode :character Mode :character Mode :character
sse nrs cp1 nor
Length:2840 Length:2840 Length:2840 Length:2840
Class :character Class :character Class :character Class :character
Mode :character Mode :character Mode :character Mode :character
mod mai geometry origen
Length:2840 Length:2840 POINT :2840 Length:2840
Class :character Class :character epsg:4326 : 0 Class :character
Mode :character Mode :character +proj=long...: 0 Mode :character
%>% summary() ec_fer
gid entidad fna gna
Min. : 265.0 Min. :0 Length:1028 Length:1028
1st Qu.: 521.8 1st Qu.:0 Class :character Class :character
Median :1408.5 Median :0 Mode :character Mode :character
Mean :1291.2 Mean :0
3rd Qu.:2006.2 3rd Qu.:0
Max. :2656.0 Max. :0
nam fun fdc sag
Length:1028 Min. :2.00 Length:1028 Length:1028
Class :character 1st Qu.:2.00 Class :character Class :character
Mode :character Median :2.00 Mode :character Mode :character
Mean :3.44
3rd Qu.:6.00
Max. :6.00
geometry origen
POINT :1028 Length:1028
epsg:4326 : 0 Class :character
+proj=long...: 0 Mode :character
%>%
ec_ind mutate(numero_empleados_estimado=as.numeric(numero_empleados_estimado)) %>%
summary()
municipio_id municipio_nombre localidad
Length:83 Length:83 Length:83
Class :character Class :character Class :character
Mode :character Mode :character Mode :character
nombre_agrupamiento_promotor tipologia iniciativa
Length:83 Length:83 Length:83
Class :character Class :character Class :character
Mode :character Mode :character Mode :character
tipo_segun_origen numero_decreto numero_decreto_de_ampliacion
Length:83 Length:83 Length:83
Class :character Class :character Class :character
Mode :character Mode :character Mode :character
ubicacion latitud longitud nombre_de_contacto
Length:83 Length:83 Length:83 Length:83
Class :character Class :character Class :character Class :character
Mode :character Mode :character Mode :character Mode :character
institucion telefono mail_1 mail_2
Length:83 Length:83 Length:83 Length:83
Class :character Class :character Class :character Class :character
Mode :character Mode :character Mode :character Mode :character
superficie_hectareas cantidad_lotes_parcelas lotes_parcelas_disponibles
Length:83 Length:83 Length:83
Class :character Class :character Class :character
Mode :character Mode :character Mode :character
reglamento_interno area_de_reserva infraestructura_basica
Length:83 Length:83 Length:83
Class :character Class :character Class :character
Mode :character Mode :character Mode :character
servicio_ adicionales centro_de_capacitación_en_el_agrupamiento
Length:83 Length:83
Class :character Class :character
Mode :character Mode :character
vinculación_con_un_centro_de_formación_externo numero_empresas
Length:83 Length:83
Class :character Class :character
Mode :character Mode :character
numero_empleados_estimado seccion_electoral interior_conurbano
Min. : 10 Length:83 Length:83
1st Qu.: 300 Class :character Class :character
Median : 700 Mode :character Mode :character
Mean : 1439
3rd Qu.: 1200
Max. :20000
NA's :4
origen
Length:83
Class :character
Mode :character
<- ec_edu %>%
ec_edu filter(nivel=="Nivel Secundario")
<- ec_fer %>%
ec_fer filter(gna=="Estación")
<- ec_ind %>%
ec_ind st_as_sf(coords=c("longitud", "latitud"), crs=4326)
Veamos un punteo que se desprende de lo anterior:
Establecimientos educativos es sin lugar a duda la base de datos más grande que tenemos. Pero también incluye distintos niveles, por lo que puede ser redundante el análisis: vamos a quedarnos sólo con escuelas de nivel secundario.
Establecimientos de salud tiene algo interesante: sólo 313 son provinciales, mientras que 25 son nacionales y 2502 son municipales. No vamos a filtrarlos porque entendemos que son establecimientos que se complementan.
En ferrocarriles tenemos conceptos como “apeadero”, “desvío” y otras que no refieren a estaciones. Vamos a filtrarlas.
Agrupamientos industriales es un archivo de excel, por lo que debemos transformarlo en geográfico utilizando las columnas de latitud y longitud. Sólo para mejorar el análisis, vamos a filtrar los casos “s/d” de número de empleados para que el
summary()
interprete correctamente el tipo de dato.
Los datos en el espacio
Para ver si están correctamente cargados sus atributos geográficos, vamos a graficarlos de conjunto. Voy a obtener un mapa de fondo con ggmap
para entender si estamos bien ubicados en la Provincia de Buenos Aires.
# ingresamos la api key de stadiamaps
register_stadiamaps(read_file('secrets/stadiamaps.txt'), write=T)
# hacemos un pequeño bbox pra probar los distintos estilos
<- ec_edu %>%
bbox_lp filter(localidad=="LA PLATA") %>%
st_bbox() %>%
as.numeric()
get_stadiamap(bbox = bbox_lp,
maptype="outdoors") %>%
ggmap()
#opciones de mapa base: “stamen_terrain”, “stamen_toner”, “stamen_toner_lite”, “stamen_watercolor”, “stamen_terrain_background”, “stamen_toner_background”, “stamen_terrain_lines”, “stamen_terrain_labels”, “stamen_toner_lines”, # “stamen_toner_labels”
Obtenemos el mapa de toda la Provincia de Buenos Aires. Es un proceso que se tarda unos minutos.
# obtenemos los límites del mapa
<- as.numeric(st_bbox(ec_edu))
bbox_pba
# obtenemos el mapa base
<- get_stadiamap(bbox = bbox_pba,
mapa_pba maptype = "stamen_toner_lite")
ggmap(mapa_pba)
Ahora sí, veamos los cuatro datasets geográficos que cargamos. Se agrega inherit.aes = FALSE
por un error en el uso simultáneo entre ggmap
y geom_sf
.
# unimos todas las bases para que sea más sencillo el graficado
<- c("origen", "geometry")
cols <- bind_rows(
ec list(select(ec_edu, cols),
select(ec_sal, cols),
select(ec_fer, cols),
select(ec_ind, cols)
)%>% rowid_to_column("ID")
)
ggmap(mapa_pba)+
geom_sf(data=ec, aes(colour=origen), inherit.aes = F)+
facet_wrap(~origen, ncol=2)+
labs(title="Elementos clave", subtitle="PBA")+
theme_void()
Resultados electorales G2023
Los resultados electorales de las elecciones generales del año 2023 ya fueron procesados para el segundo trabajo práctico de este mismo curso, por lo que tomaré directamente el archivo ya unido con sus atributos espaciales. Están los resultados de las elecciones a presidente como a gobernador para todas las listas que se presentaron.
# cargo a nivel circuito y a nivel sección por las dudas
# circuito: tiene 99 circuitos sin resultados (8,6% del total)
<- st_read('bases/G2023_procesados/G2023_pba_circ.geojson') %>%
g2023_circ mutate(area = units::set_units(st_area(geometry), km^2),
area = as.numeric(area)) # le agregamos la variable de area
Reading layer `G2023_pba_circ' from data source
`C:\Users\Usuario\Documents\personal\curso big data e inteligencia territorial\analisis G2023\bases\G2023_procesados\G2023_pba_circ.geojson'
using driver `GeoJSON'
Simple feature collection with 1146 features and 31 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -63.39326 ymin: -41.04344 xmax: -56.66336 ymax: -33.26327
Geodetic CRS: WGS 84
<- st_read('bases/G2023_procesados/G2023_pba_secc.geojson') %>%
g2023_secc mutate(area = units::set_units(st_area(geometry), km^2),
area = as.numeric(area))
Reading layer `G2023_pba_secc' from data source
`C:\Users\Usuario\Documents\personal\curso big data e inteligencia territorial\analisis G2023\bases\G2023_procesados\G2023_pba_secc.geojson'
using driver `GeoJSON'
Simple feature collection with 136 features and 21 fields
Geometry type: GEOMETRY
Dimension: XY
Bounding box: xmin: -63.39326 ymin: -41.04344 xmax: -56.66336 ymax: -33.26327
Geodetic CRS: WGS 84
Vamos a intentar mapear las variables para poder comparar. Para el caso de resultados electorales, hacemos en análisis dentro de cada partido (en qué circuitos sacaron mayor y menor porcentaje), en vez de ver porcentaje total por circuito, porque en este caso sería difícil ver por ejemplo patrones para el FIT-U porque en general daría valores bajos.
<- ec %>%
ecmutate(x = st_coordinates(.)[,1],
y = st_coordinates(.)[,2])
ggmap(mapa_pba)+
geom_bin2d(data=ec, aes(x=x, y=y))+
scale_fill_viridis_c()+
facet_wrap(~origen, ncol=2)+
theme_void()+
xlim(-59.383, -57.676)+
ylim(-35.101, -34.282)+
labs(title="Elementos clave", subtitle="PBA")
# cambiamos la forma para poder hacer un facetado
%>%
g2023_circ select(starts_with("gob_"), 'dpto_clean.x', 'circuito', 'geometry') %>%
pivot_longer(
cols = starts_with("gob_"),
names_to = "partido",
values_to = "votos") %>%
filter(partido != "gob_afirmativos") %>%
group_by(circuito) %>%
mutate(porcentaje = votos / sum(votos)) %>%
ungroup() %>%
drop_na(porcentaje) %>%
group_by(partido) %>%
mutate(porc_norm=(porcentaje - min(porcentaje)) / (max(porcentaje)-min(porcentaje))) %>%
ungroup() %>%
mutate(partido = str_remove(partido, "gob_")) %>%
ggplot()+
geom_sf(aes(fill=porc_norm), color=scales::alpha("white",0))+
facet_wrap(~partido)+
scale_fill_viridis_c()+
theme_void()+
theme(legend.text = element_blank())+
xlim(-59.383, -57.676)+
ylim(-35.101, -34.282)+
labs(fill='max', title="Resultados electorales G2023", subtitle="normalizado para cada partido")
%>%
g2023_circ select(starts_with("gob_"), 'dpto_clean.x', 'circuito', 'geometry') %>%
pivot_longer(
cols = starts_with("gob_"),
names_to = "partido",
values_to = "votos") %>%
filter(partido != "gob_afirmativos") %>%
group_by(circuito) %>%
mutate(porcentaje = votos / sum(votos)) %>%
ungroup() %>%
drop_na(porcentaje) %>%
group_by(partido) %>%
mutate(porc_norm=(porcentaje - min(porcentaje)) / (max(porcentaje)-min(porcentaje))) %>%
ungroup() %>%
mutate(partido = str_remove(partido, "gob_")) %>%
ggplot()+
geom_sf(aes(fill=porcentaje), color=scales::alpha("white",0))+
facet_wrap(~partido)+
scale_fill_viridis_c()+
theme_void()+
theme(legend.text = element_blank())+
xlim(-59.383, -57.676)+
ylim(-35.101, -34.282)+
labs(fill='%', title="Resultados electorales G2023", subtitle="% en cada circuito")
Podemos intentar superponiendo sólo dos variables, para ver si funcionaría mejor. Vamos a mapear agrupamientos industriales y voto al peronismo.
<- g2023_circ %>%
g2023_circ mutate(gob_uxp_per = gob_union_por_la_patria/gob_afirmativos)
ggplot()+
geom_sf(data=g2023_circ, aes(fill=gob_uxp_per), show.legend="polygon")+
geom_sf(data=ec_ind,aes(colour="red"), show.legend="point")+
theme_void()+
theme(legend.text = element_blank())+
scale_fill_viridis_c()+
scale_colour_manual(name="Agrup. industriales", labels=c("agrup. ind"), values=c("red"))+
xlim(-59.383, -57.676)+
ylim(-35.101, -34.282)+
labs(fill="UXP (%)", title="Resultados electorales G2023 & agrupamientos industriales", subtitle="PBA")
Es muy difícil comprender la relación entre las variables con este tipo de gráficos, incluso recortando el conurbano bonaerense. Vamos a unir los datasets de puntos a los circuitos para poder analizar todo con la misma forma geográfica.
<- c("geometry","circuito")
cols <- st_join(ec, select(g2023_circ, cols))
ec
%>% head(2) ec
Simple feature collection with 2 features and 5 fields
Geometry type: POINT
Dimension: XY
Bounding box: xmin: -58.10302 ymin: -34.9479 xmax: -57.96381 ymax: -34.90757
Geodetic CRS: WGS 84
ID origen x y circuito geometry
1 1 est. educativos -58.10302 -34.94790 0508F POINT (-58.10302 -34.9479)
2 2 est. educativos -57.96381 -34.90757 0475 POINT (-57.96381 -34.90757)
Luego vamos a hacer una tabla a nivel circuito con la información sobre los distintos elementos clave.
<- ec %>%
ec_circ as.data.frame() %>%
select(-geometry) %>%
count(circuito, origen, sort=T) %>%
pivot_wider(names_from=origen, values_from=n, values_fill=0) %>%
mutate(ec_total = rowSums(across(where(is.numeric))))
%>% head(2) ec_circ
# A tibble: 2 × 6
circuito `est. educativos` `est. de salud` `estaciones ferrocarril`
<chr> <int> <int> <int>
1 0302 44 14 2
2 0652A 43 14 1
# ℹ 2 more variables: `agrup. industriales` <int>, ec_total <dbl>
Unimos.
<- g2023_circ %>%
df left_join(ec_circ,by='circuito') %>%
st_as_sf() %>%
mutate(ec_edu_per = `est. educativos` / gob_afirmativos,
ec_sal_per = `est. de salud` / gob_afirmativos,
ec_fer_per = `estaciones ferrocarril` / gob_afirmativos,
ec_ind_per = `agrup. industriales` / gob_afirmativos,
ec_tot_per = ec_total / gob_afirmativos,# hacemos un % para matizar diferencias poblacionales
gob_fitu_per = gob_fit_unidad / gob_afirmativos,
gob_jxc_per = gob_juntos_por_el_cambio / gob_afirmativos,
gob_lla_per = gob_la_libertad_avanza / gob_afirmativos,
gob_uxp_per = gob_union_por_la_patria / gob_afirmativos,
zona = case_when(seccionprovincial_id %in% c(1,3,8)~"CONURBANO",
%in% c(2,4,5,6,7)~"INTERIOR",
seccionprovincial_id .default = as.character(seccionprovincial_id)))
%>% head(2) df
Simple feature collection with 2 features and 47 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -59.61976 ymin: -37.97514 xmax: -57.61852 ymax: -33.94143
Geodetic CRS: WGS 84
gid distrito provincia departamen cabecera circuito indec_p
1 62520 02 Buenos Aires General Pueyrredon Mar del Plata 0365B 02
2 62596 02 Buenos Aires Baradero Baradero 0111 02
indec_d circuito_id dpto_clean.x distrito_id distrito_nombre
1 357 0365B General Pueyrredon 2 Buenos Aires
2 070 00111 Baradero 2 Buenos Aires
seccionprovincial_id seccionprovincial_nombre seccion_id seccion_nombre
1 5 Sección Quinta 50 General Pueyrredón
2 2 Sección Segunda 9 Baradero
dpto_clean.y gob_fit_unidad gob_juntos_por_el_cambio
1 General Pueyrredon 222 1012
2 Baradero 6 39
gob_la_libertad_avanza gob_union_por_la_patria pre_fit_unidad
1 1962 3085 234
2 53 78 6
pre_juntos_por_el_cambio pre_la_libertad_avanza pre_union_por_la_patria
1 1040 2267 3103
2 45 59 74
dif_fit_unidad dif_juntos_por_el_cambio dif_la_libertad_avanza
1 0.05405405 0.02766798 0.1554536
2 0.00000000 0.15384615 0.1132075
dif_union_por_la_patria gob_afirmativos pre_afirmativos area
1 0.005834684 6281 6616 4.996014
2 -0.051282051 176 178 289.981616
gob_uxp_per est. educativos est. de salud estaciones ferrocarril
1 0.4911638 1 1 0
2 0.4431818 1 1 1
agrup. industriales ec_total geometry ec_edu_per
1 0 2 MULTIPOLYGON (((-57.64917 -... 0.0001592103
2 0 3 MULTIPOLYGON (((-59.40638 -... 0.0056818182
ec_sal_per ec_fer_per ec_ind_per ec_tot_per gob_fitu_per gob_jxc_per
1 0.0001592103 0.000000000 0 0.0003184206 0.03534469 0.1611208
2 0.0056818182 0.005681818 0 0.0170454545 0.03409091 0.2215909
gob_lla_per zona
1 0.3123706 INTERIOR
2 0.3011364 INTERIOR
Veamos la relación entre elementos clave y voto al oficialismo.
<- c("muy bajo", "bajo", "medio","alto","muy alto")
labs %>%
df mutate(uxp_quantiles = cut_number(gob_uxp_per,5, labels=labs)) %>%
ggplot(aes(x=uxp_quantiles, fill=zona, y=`est. educativos`, hue=zona))+
geom_boxplot()+
theme_minimal()+
labs(title="Relación entre voto al oficialismo (cuantiles) y elementos clave",
subtitle="PBA")
%>%
df mutate(uxp_quantiles = cut_number(gob_uxp_per,5, labels=labs)) %>%
ggplot(aes(x=uxp_quantiles, fill=zona, y=`est. de salud`, hue=zona))+
geom_boxplot()+
theme_minimal()+
labs(title="Relación entre voto al oficialismo (cuantiles) y elementos clave",
subtitle="PBA")
%>%
df mutate(uxp_quantiles = cut_number(gob_uxp_per,5, labels=labs)) %>%
ggplot(aes(x=uxp_quantiles, fill=zona, y=`estaciones ferrocarril`, hue=zona))+
geom_boxplot()+
theme_minimal()+
labs(title="Relación entre voto al oficialismo (cuantiles) y elementos clave",
subtitle="PBA")
%>%
df mutate(uxp_quantiles = cut_number(gob_uxp_per,5, labels=labs)) %>%
ggplot(aes(y=gob_uxp_per, x=as.character(`agrup. industriales`), fill=zona, hue=zona))+
geom_boxplot()+
theme_minimal()+
labs(title="Relación entre voto al oficialismo (%) y agrupamientos industriales",
subtitle="PBA")
%>%
df mutate(uxp_quantiles = cut_number(gob_uxp_per,5, labels=labs)) %>%
ggplot(aes(x=uxp_quantiles, fill=zona, y=ec_total, hue=zona))+
geom_boxplot()+
theme_minimal()+
labs(title="Relación entre voto al oficialismo (cuantiles) y elementos clave",
subtitle="PBA")
%>%
df mutate(uxp_quantiles = cut_number(gob_uxp_per,5, labels=labs)) %>%
ggplot(aes(x=uxp_quantiles, fill=zona, y=gob_afirmativos, hue=zona))+
geom_boxplot()+
theme_minimal()+
labs(title="Relación entre voto al oficialismo (cuantiles) y elementos clave",
subtitle="PBA")
Pareciera haber una relación positiva entre equipamientos educativos y de salud y voto al oficialismo en el conurbano bonerense. Sin embargo, también vemos que se da la misma relación cuando vemos un proxy de población (cantidad de votos afirmativos), por lo que podría darse el caso siguiente: en verdad, al oficialismo le va bien en zonas muy pobladas donde, lógicamente, hay mayor cantidad absoluta de equipamientos.
Veamos con gráficos más clásicos para analizar relaciones entre distintas variables pero usando la variable de elementos clave relativizada por población. Quizás el formateo de tablas no sea la más óptima. No logré usar ggpairs()
para hacer algo más amable, así que terminé haciendo las siguientes transformaciones: primero paso todas las variables de interés al formato long, luego separo las bases, las uno por el circuito y grafico un facetado.
<- df %>%
df_long select(((starts_with("gob_")|(starts_with("ec_"))))&ends_with("_per"), zona, circuito) %>%
pivot_longer(
cols = ends_with("_per"),
names_to = "categoria",
values_to = "valor") %>%
mutate(variable = case_when(grepl("gob_", categoria)~"voto",
grepl("ec_", categoria)~"ec"),
categoria = str_remove(categoria, "gob_"),
categoria = str_remove(categoria, "ec_"),
categoria = str_remove(categoria, "_per"),
categoria = toupper(categoria),
categoria = case_when(categoria=="EDU"~"EDUC.",
=="SAL"~"SALUD",
categoria=="FER"~"FERROC.",
categoria=="IND"~"INDUSTR.",
categoria=="TOT"~"TOTAL EC", .default = categoria)) %>%
categoriaas.data.frame()
%>% head(2) df_long
zona circuito geometry categoria valor
1 INTERIOR 0365B MULTIPOLYGON (((-57.64917 -... UXP 0.49116383
2 INTERIOR 0365B MULTIPOLYGON (((-57.64917 -... FITU 0.03534469
variable
1 voto
2 voto
<- df_long %>%
voto_data filter(variable == "voto") %>%
select(zona,circuito, categoria, valor) %>%
rename(voto_categoria = categoria, voto_valor = valor)
<- df_long %>%
ec_data filter(variable == "ec") %>%
select(zona,circuito, categoria, valor) %>%
rename(ec_categoria = categoria, ec_valor = valor)
<- voto_data %>%
combined_data inner_join(ec_data, by = c("circuito","zona"))
ggplot(combined_data, aes(x = voto_valor, y = ec_valor, color = zona)) +
geom_point(alpha=.3, size=.5) +
geom_smooth(method='lm', se=F)+
scale_y_log10() +
facet_grid(vars(ec_categoria), vars(voto_categoria), scales = "free", switch = "both")+
labs(title = "Relación entre % de voto y presencia de elementos clave", x="", y="") +
theme_minimal()+
theme(axis.text.x = element_blank(),
axis.text.y = element_blank())
En este caso, vemos que se da la relación contraria: el FIT-U y UXP tienen mejores resultados relativos donde la tasa de elementos clave sobre población es más pequeña; podríamos suponer, sectores más vulnerables. Se puede seguir indagando en esta hipótesis. LLA presenta una situación interesante: una relación positiva para el conurbano bonaerense pero no tan clara para el interior.
A modo de conclusión
Para redondear este trabajo: la relación que se ve entre presencia de elementos clave y resultados electorales es la siguiente. Para los partidos FIT-U y UXP, la relación entre la tasa de elementos clave por población es negativa en el conurbano; para el resto de los partidos es positiva. En el interior no se ve una relación tan sugerente. Podría incorporarse una variable de nivel socioeconómico para poder usar esa variable de control: ¿qué sucede con lugares ricos con baja tasa de elementos clave? También podría incorporarse la distancia como variable para verificar si la distancia a los distintos equipamientos públicos tiene relación con el voto.
Respecto a las herramientas utilizadas: usamos mapas de puntos, de densidad y coropléticos para analizar las distintas variables. Se incorporó un mapa base a través de Stadia Maps. Para ver las relaciones entre variables, volvimos a los gráficos clásicos: de cajas y de puntos.