Elecciones Generales 2023

Author

Tomás Bustos

Published

June 17, 2024

Corte de boleta en las elecciones generales de 2023 - Provincia de Buenos Aires

Este análisis se realiza en el contexto del módulo “Ciencia de Datos I” del curso de FLACSO “Big Data e Inteligencia Territorial”. La idea es explorar los resultados de las elecciones generales del año 2023 para entender cómo se dió la dinámica del corte de boleta entre los cargos provinciales y nacionales con sus particularidades territoriales.

En particular, las preguntas que orientan brevísimo texto son: ¿Hubo corte de boleta entre quienes eligieron gobernador y presidente en las últimas elecciones generales? ¿Qué partido tuvo mayor proporción de votos fugados y en qué dirección? ¿Cómo se distribuye geográficamente ese corte de boleta?

Comenzamos cargando las librerías que vamos a usar.

Cargamos los datos de los resultados electorales disponibles en https://www.argentina.gob.ar/dine/resultados-electorales/elecciones-2023.

En este caso, nos enfrentamos a una base muy pesada que no vamos a usar en su totalidad, por lo que vamos a utilizar una función especial que realiza la carga por partes (chunks) filtrando los casos donde el distrito es “Buenos Aires” y los cargos son ejecutivos.

Code
path <- "bases/2023_Generales/ResultadosElectorales_2023.csv"

cargos <- c("GOBERNADOR Y VICE","PRESIDENTE Y VICE","INTENDENTE")

f <- function(x, pos){
  filter(x, (distrito_nombre=="Buenos Aires"), 
         (cargo_nombre %in% cargos))
}
g2023 <- read_csv_chunked(path, DataFrameCallback$new(f), chunk_size=10000)

Luego, vamos a realizar ciertas transformaciones en algunas de sus variables (sección y circuito electoral) para poder después unir los resultados al archivo geográfico que nos permitirá desplegar los resultados en un mapa de la Provincia de Buenos Aires. Por último, ejecutamos algunas funciones para dar un vistazo general a la base que estamos trabajando.

Code
g2023 <- g2023 %>% 
  mutate(dpto_clean = stringi::stri_trans_general(seccion_nombre,"Latin-ASCII"),
         dpto_clean = case_when(dpto_clean == "General La Madrid"~"General Lamadrid",
                                dpto_clean == "Canuelas"~"Ca?uelas", 
                                dpto_clean == "Adolfo Gonzales Chaves"~"A. Gonzales Chaves",
                                dpto_clean == "Coronel de Marina L. Rosales"~"Cnel. de Marina L.Rosales",
         TRUE ~ as.character(dpto_clean)),
         agrupacion_nombre = ifelse(agrupacion_nombre == "FRENTE DE IZQUIERDA Y DE TRABAJADORES - UNIDAD", "FIT-UNIDAD", agrupacion_nombre))
print("Vemos filas y columnas de la base: ")
[1] "Vemos filas y columnas de la base: "
Code
dim(g2023)
[1] 1103831      24
Code
print("Resumen de la base: ")
[1] "Resumen de la base: "
Code
glimpse(g2023) 
Rows: 1,103,831
Columns: 24
$ año                      <dbl> 2023, 2023, 2023, 2023, 2023, 2023, 2023, 202…
$ eleccion_tipo            <chr> "GENERAL", "GENERAL", "GENERAL", "GENERAL", "…
$ recuento_tipo            <chr> "PROVISORIO", "PROVISORIO", "PROVISORIO", "PR…
$ padron_tipo              <chr> "NORMAL", "NORMAL", "NORMAL", "NORMAL", "NORM…
$ distrito_id              <dbl> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, …
$ distrito_nombre          <chr> "Buenos Aires", "Buenos Aires", "Buenos Aires…
$ seccionprovincial_id     <dbl> 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, …
$ seccionprovincial_nombre <chr> "Sección Tercera", "Sección Tercera", "Secció…
$ seccion_id               <dbl> 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 6…
$ seccion_nombre           <chr> "La Matanza", "La Matanza", "La Matanza", "La…
$ circuito_id              <chr> "0635B", "0635B", "0635B", "0635B", "0635B", …
$ circuito_nombre          <chr> "0635B", "0635B", "0635B", "0635B", "0635B", …
$ mesa_id                  <dbl> 2405, 2405, 2406, 2406, 2406, 2406, 2406, 240…
$ mesa_tipo                <chr> "NATIVOS", "NATIVOS", "NATIVOS", "NATIVOS", "…
$ mesa_electores           <dbl> 350, 350, 354, 354, 354, 354, 354, 354, 354, …
$ cargo_id                 <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
$ cargo_nombre             <chr> "PRESIDENTE Y VICE", "PRESIDENTE Y VICE", "PR…
$ agrupacion_id            <dbl> 0, 0, 134, 135, 132, 136, 133, 0, 0, 0, 0, 0,…
$ agrupacion_nombre        <chr> NA, NA, "UNION POR LA PATRIA", "LA LIBERTAD A…
$ lista_numero             <dbl> 0, 0, NA, NA, NA, NA, NA, 0, 0, 0, 0, 0, NA, …
$ lista_nombre             <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
$ votos_tipo               <chr> "RECURRIDO", "COMANDO", "POSITIVO", "POSITIVO…
$ votos_cantidad           <dbl> 0, 0, 164, 66, 33, 13, 5, 7, 2, 0, 0, 0, 155,…
$ dpto_clean               <chr> "La Matanza", "La Matanza", "La Matanza", "La…

Hacemos un pequeño gráfico para ver qué categorías tenemos para las variables de sección provincial y cargo nombre. Además, vemos si hay grandes diferencias entre la cantidad de votos para cada categoría en las distintas secciones.

Code
g2023 %>% 
  #sample_n(10000) %>% # usamos sample_n para probar que el gráfico funcione bien, antes de utilizar la totalidad de la base que suele tardar
    ggplot(aes(y=seccionprovincial_nombre, x=votos_cantidad, fill=cargo_nombre)) +
  geom_col(position="fill")+
  labs(title="Votos por cargo por sección",
       subtitle='Elecciones G2023',
       caption='*Datos provisorios')+
  xlab('Votos')+
  ylab('Sección provincial')+
  theme_minimal()+
  scale_fill_brewer(palette="Pastel1") 

Diferencia de votos entre presidente y gobernador

Construimos una tabla agregada a nivel de sección provincial (una agrupación particular de secciones electorales o municipios) de votos afirmativos por partido. Excluímos a Hacemos por Nuestro País por no llevar un candidato a gobernador en la Provincia de Buenos Aires. También excluímos la categoría de voto a intendente porque deberíamos hacer una limpieza de nombres de partidos para homogeneizarlo con los partidos provinciales y nacionales.

Code
tabla_agg <- g2023 %>%
   filter(cargo_nombre %in% cargos[1:2], # nos quedamos sólo con gobernador y presidente porque las intendencias tienen nombres propios que deben ser estandarizados
          agrupacion_nombre != 'HACEMOS POR NUESTRO PAIS') %>% # sacamos el partido Hacemos por Nuestro País porque no llevaba boleta a gobernador de la PBA
  drop_na(agrupacion_nombre) %>% # eliminamos los votos negativos (blanco, nulo, etc.)
  group_by(seccionprovincial_nombre, cargo_nombre, agrupacion_nombre) %>%
  summarise(votos = sum(votos_cantidad)) %>% 
  mutate(porcentaje = votos / sum(votos) * 100) %>%
  ungroup() 
`summarise()` has grouped output by 'seccionprovincial_nombre', 'cargo_nombre'.
You can override using the `.groups` argument.
Code
knitr::kable(head(tabla_agg))
seccionprovincial_nombre cargo_nombre agrupacion_nombre votos porcentaje
Sección Capital GOBERNADOR Y VICE FIT-UNIDAD 18514 4.319666
Sección Capital GOBERNADOR Y VICE JUNTOS POR EL CAMBIO 140137 32.696606
Sección Capital GOBERNADOR Y VICE LA LIBERTAD AVANZA 88716 20.699117
Sección Capital GOBERNADOR Y VICE UNION POR LA PATRIA 181231 42.284612
Sección Capital PRESIDENTE Y VICE FIT-UNIDAD 16797 4.051473
Sección Capital PRESIDENTE Y VICE JUNTOS POR EL CAMBIO 129295 31.186232

Graficamos la cantidad de votos por sección por partido.

Code
orden_seccion <- c("Sección Primera",'Sección Segunda','Sección Tercera',
                   'Sección Cuarta', 'Sección Quinta', 'Sección Sexta',
                   'Sección Séptima', 'Sección Capital')
tabla_agg %>% 
ggplot(aes(x = agrupacion_nombre, 
           y = votos, 
           fill = cargo_nombre, 
           label=round(votos/1e3,0))) + # agregamos datos
  geom_bar(stat = "identity", position = "dodge") + # graficamos barra
  geom_text(position = position_dodge(width = 1), 
            hjust=0.8, vjust = 0.5, size = 3, color = "black")+ #graficamos etiquetas
  coord_flip()+
  labs(title = "Votos afirmativos por partido por sección", 
       subtitle='Elecciones G2023', 
       x = "", y = "en miles de votos", fill="", 
       caption='*Datos provisorios') +
  facet_wrap(~factor(seccionprovincial_nombre,orden_seccion),
             ncol=4, scales='free_x')+
  theme_minimal()+
  guides(fill = guide_legend(reverse = TRUE))+
  theme(axis.line = element_line(color='black'),
    plot.background = element_blank(),
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    panel.border = element_blank(), 
    legend.position="bottom",
    axis.text.x=element_blank())+ # limpiamos el gráfico
  scale_fill_brewer(palette="Pastel1") 

Vemos la diferencia absoluta y en porcentaje para cada agrupación en cada sección provincial. Vamos a realizar dos gráficos, invirtiendo el orden de las variables agrupación y sección para ver con más claridad la relación inter-partidos e intra-partidos.

Code
tabla_dif <- tabla_agg %>% 
  select(-porcentaje) %>% 
  pivot_wider(names_from=cargo_nombre, values_from=votos) %>% 
  janitor::clean_names() %>% 
  mutate(diferencia_abs = presidente_y_vice - gobernador_y_vice, 
         diferencia_per = diferencia_abs / gobernador_y_vice)

knitr::kable(head(tabla_dif))
seccionprovincial_nombre agrupacion_nombre gobernador_y_vice presidente_y_vice diferencia_abs diferencia_per
Sección Capital FIT-UNIDAD 18514 16797 -1717 -0.0927406
Sección Capital JUNTOS POR EL CAMBIO 140137 129295 -10842 -0.0773671
Sección Capital LA LIBERTAD AVANZA 88716 97324 8608 0.0970287
Sección Capital UNION POR LA PATRIA 181231 171174 -10057 -0.0554927
Sección Cuarta FIT-UNIDAD 6266 7488 1222 0.1950207
Sección Cuarta JUNTOS POR EL CAMBIO 129568 119572 -9996 -0.0771487
Code
orden_agrup <- c("UNION POR LA PATRIA","LA LIBERTAD AVANZA",
                 'JUNTOS POR EL CAMBIO','FIT-UNIDAD')

tabla_dif %>% 
ggplot(aes(x = factor(agrupacion_nombre, orden_agrup), 
           y = diferencia_per,
           label=round(diferencia_per*100)))+
  geom_col(width = 0.05)+
  geom_point(size=2)+
  geom_hline(yintercept=0)+
  facet_wrap(~factor(seccionprovincial_nombre, orden_seccion), 
             ncol=4)+
  coord_flip(ylim=c(-0.25,0.25))+
  labs(title='Diferencia % entre voto a presidente y gobernador',
       subtitle='Valores positivos indican mayor voto a presidente que a gobernador, valores negativos indican la situación inversa.',
       y='Diferencia (%)', x='')+
  theme_minimal()+
  theme(axis.text.x=element_blank())

Code
tabla_dif %>% 
ggplot(aes(x = factor(seccionprovincial_nombre, orden_seccion), 
           y = diferencia_per,
           label=round(diferencia_per*100)))+
  geom_col(width = 0.05)+
  geom_point(size=2)+
  geom_hline(yintercept=0)+
  facet_wrap(~factor(agrupacion_nombre, orden_agrup), 
             ncol=4)+
  coord_flip(ylim=c(-0.25,0.25))+
  labs(title='Diferencia % entre voto a presidente y gobernador',
       subtitle='Valores positivos indican mayor voto a presidente que a gobernador, valores negativos indican la situación inversa.',
       y='Diferencia (%)', x='')+
  theme_minimal()+
  theme(axis.text.x=element_blank())

Con ambos gráficos vemos qué:

  • Unión por la Patria tiene poco corte de boleta en general; el valor más alto lo tiene en la Sección Capital en favor del gobernador.

  • La Libertad Avanza tiene mucho corte de boleta en favor del presidente; destaca la Sección Cuarta.

  • Juntos por el Cambio tiene mucho corte de boleta en favor del gobernador.

  • FIT-Unidad tiene un comportamiento disímil: en la Sección Primera, Tercera y Capital tiene corte en favor del gobernador; en el resto en favor del presidente.

Explorando la dimensión territorial

Cargo circuitos electorales disponibles en el portal de datos abiertos de la Provincia de Buenos Aires: https://catalogo.datos.gba.gob.ar/tr/dataset/circuitos-electorales. Transformamos el circuito y la sección para unir con los resultados electorales.

Code
path <- "bases/circuitos-electorales/circuitos-electorales.geojson"
circ <- read_sf(path) %>% 
  mutate(circuito_id = str_pad(circuito, 5, "0", side="left"),
         dpto_clean = stringi::stri_trans_general(departamen,"Latin-ASCII"))

circ %>% 
  ggplot()+
  geom_sf(aes(fill=circuito_id),color=NA)+ 
  theme_void()+
  labs(title='Circuitos electorales',
    subtitle='Provincia de Buenos Aires')+
  theme(legend.position = "none")

Construimos tabla de resultados agregada a nivel circuito, departamento y a nivel sección provincial.

Code
print('Circuito: ')
[1] "Circuito: "
Code
tabla_circ <- g2023 %>%
   filter(cargo_nombre %in% cargos[1:2],
          agrupacion_nombre != 'HACEMOS POR NUESTRO PAIS') %>%
  drop_na(agrupacion_nombre) %>% 
  group_by(distrito_id, distrito_nombre, seccionprovincial_id, seccionprovincial_nombre, seccion_id, seccion_nombre, dpto_clean, circuito_id, cargo_nombre, agrupacion_nombre) %>%
  summarise(votos = sum(votos_cantidad)) %>% 
  mutate(cargo_nombre = case_when(cargo_nombre=="PRESIDENTE Y VICE"~"PRE",
                                  cargo_nombre=="GOBERNADOR Y VICE"~"GOB")) %>% 
  ungroup() %>% 
  pivot_wider(names_from=c("cargo_nombre","agrupacion_nombre"), values_from='votos') %>% 
  janitor::clean_names()

knitr::kable(head(tabla_circ))
distrito_id distrito_nombre seccionprovincial_id seccionprovincial_nombre seccion_id seccion_nombre dpto_clean circuito_id gob_fit_unidad gob_juntos_por_el_cambio gob_la_libertad_avanza gob_union_por_la_patria pre_fit_unidad pre_juntos_por_el_cambio pre_la_libertad_avanza pre_union_por_la_patria
2 Buenos Aires 1 Sección Primera 16 Campana Campana 00155 456 6156 3130 4637 466 5629 3789 5178
2 Buenos Aires 1 Sección Primera 16 Campana Campana 00156 334 3148 2471 4499 377 2844 3182 5313
2 Buenos Aires 1 Sección Primera 16 Campana Campana 0155A 473 5958 3158 4135 481 4989 3514 4234
2 Buenos Aires 1 Sección Primera 16 Campana Campana 0156A 496 4649 3602 4636 510 4174 4314 5168
2 Buenos Aires 1 Sección Primera 16 Campana Campana 0156B 268 2402 1938 3336 272 2184 2400 4017
2 Buenos Aires 1 Sección Primera 35 Escobar Escobar 00773 871 4431 7737 9298 844 4356 8095 8814
Code
print('Departamento: ')
[1] "Departamento: "
Code
tabla_dpto <- g2023 %>%
   filter(cargo_nombre %in% cargos[1:2],
          agrupacion_nombre != 'HACEMOS POR NUESTRO PAIS') %>%
  drop_na(agrupacion_nombre) %>% 
  group_by(distrito_id, distrito_nombre, seccionprovincial_id, seccionprovincial_nombre, seccion_id, seccion_nombre, dpto_clean, cargo_nombre, agrupacion_nombre) %>%
  summarise(votos = sum(votos_cantidad)) %>% 
  mutate(cargo_nombre = case_when(cargo_nombre=="PRESIDENTE Y VICE"~"PRE",
                                  cargo_nombre=="GOBERNADOR Y VICE"~"GOB")) %>% 
  ungroup() %>% 
  pivot_wider(names_from=c("cargo_nombre","agrupacion_nombre"), values_from='votos') %>% 
  janitor::clean_names()

knitr::kable(head(tabla_dpto))
distrito_id distrito_nombre seccionprovincial_id seccionprovincial_nombre seccion_id seccion_nombre dpto_clean gob_fit_unidad gob_juntos_por_el_cambio gob_la_libertad_avanza gob_union_por_la_patria pre_fit_unidad pre_juntos_por_el_cambio pre_la_libertad_avanza pre_union_por_la_patria
2 Buenos Aires 1 Sección Primera 16 Campana Campana 2027 22313 14299 21243 2106 19820 17199 23910
2 Buenos Aires 1 Sección Primera 35 Escobar Escobar 5307 29981 42106 63560 5274 29676 44742 63308
2 Buenos Aires 1 Sección Primera 45 General Las Heras General Las Heras 253 3042 2375 4764 275 2924 2822 4694
2 Buenos Aires 1 Sección Primera 51 General Rodríguez General Rodriguez 2101 13063 17633 32504 2153 12543 19316 31331
2 Buenos Aires 1 Sección Primera 52 General San Martín General San Martin 11062 66508 61314 114463 10200 62941 63294 113590
2 Buenos Aires 1 Sección Primera 53 San Miguel San Miguel 7385 54877 43448 71799 7081 49453 48338 75578
Code
print('Sección provincial: ')
[1] "Sección provincial: "
Code
tabla_seccp <- g2023 %>%
   filter(cargo_nombre %in% cargos[1:2],
          agrupacion_nombre != 'HACEMOS POR NUESTRO PAIS') %>%
  drop_na(agrupacion_nombre) %>% 
  group_by(distrito_id, distrito_nombre, seccionprovincial_id, seccionprovincial_nombre, cargo_nombre, agrupacion_nombre) %>%
  summarise(votos = sum(votos_cantidad)) %>% 
  mutate(cargo_nombre = case_when(cargo_nombre=="PRESIDENTE Y VICE"~"PRE",
                                  cargo_nombre=="GOBERNADOR Y VICE"~"GOB")) %>% 
  ungroup() %>% 
  pivot_wider(names_from=c("cargo_nombre","agrupacion_nombre"), values_from='votos') %>% 
  janitor::clean_names()

knitr::kable(head(tabla_seccp))
distrito_id distrito_nombre seccionprovincial_id seccionprovincial_nombre gob_fit_unidad gob_juntos_por_el_cambio gob_la_libertad_avanza gob_union_por_la_patria pre_fit_unidad pre_juntos_por_el_cambio pre_la_libertad_avanza pre_union_por_la_patria
2 Buenos Aires 1 Sección Primera 139903 885788 828607 1490895 131805 839484 884650 1507235
2 Buenos Aires 2 Sección Segunda 10266 137229 122830 165092 10635 129476 142656 170051
2 Buenos Aires 3 Sección Tercera 147989 716515 766781 1744787 140134 679505 803778 1729564
2 Buenos Aires 4 Sección Cuarta 6266 129568 96047 136655 7488 119572 119435 135114
2 Buenos Aires 5 Sección Quinta 27060 294917 228045 306639 27723 276082 265801 306537
2 Buenos Aires 6 Sección Sexta 12391 142893 134436 139141 13414 139636 156316 137433

Construimos la tabla de circuitos agregada a nivel departamento y sección provincial.

Code
equi_seccp <- g2023 %>% 
  select(dpto_clean, seccionprovincial_nombre) %>% 
  distinct()

geo_dpto <- circ %>% 
  group_by(dpto_clean) %>% 
  summarise(geometry=st_union(geometry))
Warning: Returning more (or less) than 1 row per `summarise()` group was deprecated in
dplyr 1.1.0.
ℹ Please use `reframe()` instead.
ℹ When switching from `summarise()` to `reframe()`, remember that `reframe()`
  always returns an ungrouped data frame and adjust accordingly.
Code
geo_seccp <- circ %>% 
  left_join(equi_seccp, by="dpto_clean") %>% 
  group_by(seccionprovincial_nombre) %>% 
  summarise(geometry=st_union(geometry))

ggplot()+
  labs(title='Distintos niveles geográficos')+
  geom_sf(data=circ, fill=NA)+
  geom_sf(data=geo_dpto, color='blue', fill=NA)+
  geom_sf(data=geo_seccp, color='red', fill=NA)+
  theme_void()

Teniendo las tablas, unimos con los archivos geográficos.

Code
df_seccp <- left_join(geo_seccp, tabla_seccp, by="seccionprovincial_nombre")%>% 
  mutate(dif_fit_unidad = (pre_fit_unidad - gob_fit_unidad)/gob_fit_unidad,
         dif_juntos_por_el_cambio = (pre_juntos_por_el_cambio - gob_juntos_por_el_cambio)/gob_juntos_por_el_cambio,
         dif_la_libertad_avanza = (pre_la_libertad_avanza - gob_la_libertad_avanza)/gob_la_libertad_avanza,
         dif_union_por_la_patria = (pre_union_por_la_patria - gob_union_por_la_patria)/gob_union_por_la_patria,
         gob_afirmativos = gob_fit_unidad+gob_juntos_por_el_cambio+gob_la_libertad_avanza+gob_union_por_la_patria, 
         pre_afirmativos = pre_fit_unidad+gob_juntos_por_el_cambio+pre_la_libertad_avanza+pre_union_por_la_patria) %>% 
  st_as_sf(wkt='geometry')

df_dpto <- left_join(geo_dpto, tabla_dpto, by="dpto_clean")%>% 
  mutate(dif_fit_unidad = (pre_fit_unidad - gob_fit_unidad)/gob_fit_unidad,
         dif_juntos_por_el_cambio = (pre_juntos_por_el_cambio - gob_juntos_por_el_cambio)/gob_juntos_por_el_cambio,
         dif_la_libertad_avanza = (pre_la_libertad_avanza - gob_la_libertad_avanza)/gob_la_libertad_avanza,
         dif_union_por_la_patria = (pre_union_por_la_patria - gob_union_por_la_patria)/gob_union_por_la_patria,
         gob_afirmativos = gob_fit_unidad+gob_juntos_por_el_cambio+gob_la_libertad_avanza+gob_union_por_la_patria, 
         pre_afirmativos = pre_fit_unidad+gob_juntos_por_el_cambio+pre_la_libertad_avanza+pre_union_por_la_patria) %>% 
  st_as_sf(wkt='geometry')

df_circ <- left_join(circ, tabla_circ, by="circuito_id")%>% 
  mutate(dif_fit_unidad = (pre_fit_unidad - gob_fit_unidad)/gob_fit_unidad,
         dif_juntos_por_el_cambio = (pre_juntos_por_el_cambio - gob_juntos_por_el_cambio)/gob_juntos_por_el_cambio,
         dif_la_libertad_avanza = (pre_la_libertad_avanza - gob_la_libertad_avanza)/gob_la_libertad_avanza,
         dif_union_por_la_patria = (pre_union_por_la_patria - gob_union_por_la_patria)/gob_union_por_la_patria,
         gob_afirmativos = gob_fit_unidad+gob_juntos_por_el_cambio+gob_la_libertad_avanza+gob_union_por_la_patria, 
         pre_afirmativos = pre_fit_unidad+gob_juntos_por_el_cambio+pre_la_libertad_avanza+pre_union_por_la_patria) %>% 
  st_as_sf(wkt='geometry')

Vamos a ver los resultados anteriores en los distintos mapas.

Code
df_seccp %>% 
  select(starts_with("dif"), seccionprovincial_nombre) %>% 
  pivot_longer(starts_with("dif"), names_to="agrup", values_to='dif_per') %>% 
  mutate(agrup = str_to_title(str_replace_all(str_remove(agrup, "dif_"), "_"," "))) %>% 
  #mutate(min=min(dif_per), max=max(dif_per))
  ggplot()+
  geom_sf(aes(fill=dif_per),color=NA)+
  facet_wrap(~agrup)+
  theme_void()+
  labs(title='Corte de boleta por sección provincial', 
       subtitle='Elección G2023',
       fill='Diferencia (%)')+
  scale_fill_distiller(palette='RdYlGn', na.value="white",
                       limits=c(-0.25,0.25))+
  guides(fill=guide_colorbar(ticks.colour=NA))

Para realizar los mapas a nivel departamento vamos a construirlo como mapas aparte porque no quedan bien las escalas al pintar los distintos polígonos.

Code
temp <- df_dpto %>% 
  select(starts_with("dif"), dpto_clean) %>%
  pivot_longer(starts_with("dif"), names_to="agrup", values_to='dif_per') %>% 
  mutate(agrup = str_to_title(str_replace_all(str_remove(agrup, "dif_"), "_"," ")))

limits <- temp %>% group_by(agrup) %>% summarise(min=min(dif_per), max=max(dif_per))
agrups <- unique(temp$agrup)

temp %>% 
    filter(agrup=="Union Por La Patria") %>% 
    ggplot()+
    geom_sf(aes(fill=dif_per))+ # color=NA me da un error que no logro solucionar
    theme_void()+
    labs(title='Corte de boleta por departamento', 
        subtitle='Elección G2023: Union Por La Patria',
        fill='Diferencia (%)') +
    scale_fill_distiller(palette='RdYlGn', na.value="white", 
                         limits=c(-0.2, 0.2))+
    guides(fill=guide_colorbar(ticks.colour=NA)) 

Code
temp %>% 
    filter(agrup=="La Libertad Avanza") %>% 
    ggplot()+
    geom_sf(aes(fill=dif_per))+ # color=NA me da un error que no logro solucionar
    theme_void()+
    labs(title='Corte de boleta por departamento', 
        subtitle='Elección G2023: La Libertad Avanza',
        fill='Diferencia (%)') +
    scale_fill_distiller(palette='RdYlGn', na.value="white", 
                         limits=c(-0.8, 0.8))+
    guides(fill=guide_colorbar(ticks.colour=NA)) 

Code
temp %>% 
    filter(agrup=="Juntos Por El Cambio") %>% 
    ggplot()+
    geom_sf(aes(fill=dif_per))+ # color=NA me da un error que no logro solucionar
    theme_void()+
    labs(title='Corte de boleta por departamento', 
        subtitle='Elección G2023: Juntos Por El Cambio',
        fill='Diferencia (%)') +
    scale_fill_distiller(palette='RdYlGn', na.value="white", 
                         limits=c(-0.21, 0.21))+
    guides(fill=guide_colorbar(ticks.colour=NA)) 

Code
temp %>% 
    filter(agrup=="Fit Unidad") %>% 
    ggplot()+
    geom_sf(aes(fill=dif_per))+ # color=NA me da un error que no logro solucionar
    theme_void()+
    labs(title='Corte de boleta por departamento', 
        subtitle='Elección G2023: Fit Unidad',
        fill='Diferencia (%)') +
    scale_fill_distiller(palette='RdYlGn', na.value="white", 
                         limits=c(-1.7, 1.7))+
    guides(fill=guide_colorbar(ticks.colour=NA))