Nettoyage résultats électoraux

Passage des données data.gouv.fr en mode 'tidy'

Ce script propose de nettoyer les données de résultats des élections présidentielles 2022, restituées au niveau du bureau de vote sur data.gouv.fr.

https://www.data.gouv.fr/fr/datasets/election-presidentielle-des-10-et-24-avril-2022-resultats-definitifs-du-1er-tour/

On propose ici un nettoyage du dataset resultats-par-niveau-burvot-t1-france-entiere.txt.

# Chargement des libraires
library(data.table)
library(janitor)
library(snakecase)
import <- fread("https://www.data.gouv.fr/fr/datasets/r/79b5cac4-4957-486b-bbda-322d80868224", encoding = "Latin-1")
## Warning in fread("https://www.data.gouv.fr/fr/datasets/r/79b5cac4-4957-486b-
## bbda-322d80868224", : Detected 28 column names but the data has 105 columns
## (i.e. invalid file). Added 77 extra default column names at the end.
head(import)
##    Code du département Libellé du département Code de la circonscription
## 1:                  01                    Ain                          4
## 2:                  01                    Ain                          5
## 3:                  01                    Ain                          5
## 4:                  01                    Ain                          5
## 5:                  01                    Ain                          5
## 6:                  01                    Ain                          5
##    Libellé de la circonscription Code de la commune   Libellé de la commune
## 1:          4ème circonscription                  1 L'Abergement-Clémenciat
## 2:          5ème circonscription                  2   L'Abergement-de-Varey
## 3:          5ème circonscription                  4       Ambérieu-en-Bugey
## 4:          5ème circonscription                  4       Ambérieu-en-Bugey
## 5:          5ème circonscription                  4       Ambérieu-en-Bugey
## 6:          5ème circonscription                  4       Ambérieu-en-Bugey
##    Code du b.vote Inscrits Abstentions % Abs/Ins Votants % Vot/Ins Blancs
## 1:           0001      645         108     16,74     537     83,26     16
## 2:           0001      213          38     17,84     175     82,16      3
## 3:           0001     1129         266     23,56     863     76,44     18
## 4:           0002     1128         265     23,49     863     76,51     15
## 5:           0003     1213         246     20,28     967     79,72     10
## 6:           0004      933         224     24,01     709     75,99      8
##    % Blancs/Ins % Blancs/Vot Nuls % Nuls/Ins % Nuls/Vot Exprimés % Exp/Ins
## 1:         2,48         2,98    1       0,16       0,19      520     80,62
## 2:         1,41         1,71    1       0,47       0,57      171     80,28
## 3:         1,59         2,09    5       0,44       0,58      840     74,40
## 4:         1,33         1,74    6       0,53       0,70      842     74,65
## 5:         0,82         1,03    8       0,66       0,83      949     78,24
## 6:         0,86         1,13    4       0,43       0,56      697     74,71
##    % Exp/Vot N°Panneau Sexe     Nom   Prénom Voix % Voix/Ins % Voix/Exp V29 V30
## 1:     96,83         1    F ARTHAUD Nathalie    3       0,47       0,58   2   M
## 2:     97,71         1    F ARTHAUD Nathalie    2       0,94       1,17   2   M
## 3:     97,33         1    F ARTHAUD Nathalie    4       0,35       0,48   2   M
## 4:     97,57         1    F ARTHAUD Nathalie    6       0,53       0,71   2   M
## 5:     98,14         1    F ARTHAUD Nathalie    8       0,66       0,84   2   M
## 6:     98,31         1    F ARTHAUD Nathalie    4       0,43       0,57   2   M
##        V31    V32 V33  V34  V35 V36 V37    V38      V39 V40   V41   V42 V43 V44
## 1: ROUSSEL Fabien   6 0,93 1,15   3   M MACRON Emmanuel 150 23,26 28,85   4   M
## 2: ROUSSEL Fabien   7 3,29 4,09   3   M MACRON Emmanuel  50 23,47 29,24   4   M
## 3: ROUSSEL Fabien  30 2,66 3,57   3   M MACRON Emmanuel 159 14,08 18,93   4   M
## 4: ROUSSEL Fabien  13 1,15 1,54   3   M MACRON Emmanuel 201 17,82 23,87   4   M
## 5: ROUSSEL Fabien  18 1,48 1,90   3   M MACRON Emmanuel 229 18,88 24,13   4   M
## 6: ROUSSEL Fabien  21 2,25 3,01   3   M MACRON Emmanuel 156 16,72 22,38   4   M
##         V45  V46 V47  V48  V49 V50 V51    V52    V53 V54   V55   V56 V57 V58
## 1: LASSALLE Jean  18 2,79 3,46   5   F LE PEN Marine 149 23,10 28,65   6   M
## 2: LASSALLE Jean  10 4,69 5,85   5   F LE PEN Marine  23 10,80 13,45   6   M
## 3: LASSALLE Jean  24 2,13 2,86   5   F LE PEN Marine 237 20,99 28,21   6   M
## 4: LASSALLE Jean  19 1,68 2,26   5   F LE PEN Marine 210 18,62 24,94   6   M
## 5: LASSALLE Jean  28 2,31 2,95   5   F LE PEN Marine 227 18,71 23,92   6   M
## 6: LASSALLE Jean  16 1,71 2,30   5   F LE PEN Marine 172 18,44 24,68   6   M
##        V59  V60 V61  V62  V63 V64 V65       V66      V67 V68   V69   V70 V71
## 1: ZEMMOUR Éric  43 6,67 8,27   7   M MÉLENCHON Jean-Luc  66 10,23 12,69   8
## 2: ZEMMOUR Éric  14 6,57 8,19   7   M MÉLENCHON Jean-Luc  41 19,25 23,98   8
## 3: ZEMMOUR Éric  69 6,11 8,21   7   M MÉLENCHON Jean-Luc 216 19,13 25,71   8
## 4: ZEMMOUR Éric  68 6,03 8,08   7   M MÉLENCHON Jean-Luc 194 17,20 23,04   8
## 5: ZEMMOUR Éric  74 6,10 7,80   7   M MÉLENCHON Jean-Luc 227 18,71 23,92   8
## 6: ZEMMOUR Éric  40 4,29 5,74   7   M MÉLENCHON Jean-Luc 202 21,65 28,98   8
##    V72     V73  V74 V75  V76  V77 V78 V79   V80     V81 V82  V83  V84 V85 V86
## 1:   F HIDALGO Anne   5 0,78 0,96   9   M JADOT Yannick  30 4,65 5,77  10   F
## 2:   F HIDALGO Anne   3 1,41 1,75   9   M JADOT Yannick  10 4,69 5,85  10   F
## 3:   F HIDALGO Anne  15 1,33 1,79   9   M JADOT Yannick  25 2,21 2,98  10   F
## 4:   F HIDALGO Anne  19 1,68 2,26   9   M JADOT Yannick  46 4,08 5,46  10   F
## 5:   F HIDALGO Anne  16 1,32 1,69   9   M JADOT Yannick  65 5,36 6,85  10   F
## 6:   F HIDALGO Anne   8 0,86 1,15   9   M JADOT Yannick  15 1,61 2,15  10   F
##         V87     V88 V89  V90  V91 V92 V93    V94      V95 V96  V97  V98 V99
## 1: PÉCRESSE Valérie  26 4,03 5,00  11   M POUTOU Philippe   3 0,47 0,58  12
## 2: PÉCRESSE Valérie   8 3,76 4,68  11   M POUTOU Philippe   3 1,41 1,75  12
## 3: PÉCRESSE Valérie  40 3,54 4,76  11   M POUTOU Philippe   8 0,71 0,95  12
## 4: PÉCRESSE Valérie  42 3,72 4,99  11   M POUTOU Philippe   4 0,35 0,48  12
## 5: PÉCRESSE Valérie  35 2,89 3,69  11   M POUTOU Philippe   3 0,25 0,32  12
## 6: PÉCRESSE Valérie  33 3,54 4,73  11   M POUTOU Philippe   4 0,43 0,57  12
##    V100          V101    V102 V103 V104 V105
## 1:    M DUPONT-AIGNAN Nicolas   21 3,26 4,04
## 2:    M DUPONT-AIGNAN Nicolas    0 0,00 0,00
## 3:    M DUPONT-AIGNAN Nicolas   13 1,15 1,55
## 4:    M DUPONT-AIGNAN Nicolas   20 1,77 2,38
## 5:    M DUPONT-AIGNAN Nicolas   19 1,57 2,00
## 6:    M DUPONT-AIGNAN Nicolas   26 2,79 3,73

On peut voir que le format du jeu de données est peu satisfaisant pour être analysé avec l’ensemble des résultats sur un bureau de vote donné qui sont distribués sur 1 ligne avec un grand nombre de colonnes et des noms de colonnes peu clairs.

importDT <- import %>% 
  clean_names() %>% 
  setDT() %>% 
  remove_empty(which = "cols") 

On remplace ici les noms de colonnes en “v” par les prefixes correspondant tout en continuant la numérotation séquentielle à chaque nouveau candidat.

prefixes <- c("n_panneau_", "sexe_", "nom_", "prenom_", "voix_", "percent_voix_ins_", "percent_voix_exp_") 

colnamesToReplace <- colnames(importDT)[grepl(pattern = "^v\\d", colnames(importDT))]
if(length(colnamesToReplace)>1){
  nCandidats <- length(colnamesToReplace) / length(prefixes) + 1 
  newColnames <- paste0(prefixes, sort(rep(2:nCandidats, length(prefixes))))
  setnames(importDT, old = colnamesToReplace, new = newColnames, skip_absent = TRUE)
}

Les résultats sont encodés en character, on substitue les “,” par des “.” et on transforme en numérique.

cols_to_transform <- colnames(importDT)[grepl(pattern = "voix", colnames(importDT))]
cleaned_dt <- copy(importDT) %>% 
  .[, (cols_to_transform) := lapply(.SD, function(.x) as.numeric(gsub(pattern = ",", replacement = ".", x = .x))), .SDcols = cols_to_transform]

On fait l’équivalent d’un pivot_longer avec data.table pour obtenir 1 ligne / bureau de vote / candidat.

resultatsVotes <- melt(cleaned_dt, id=c("code_de_la_commune", "code_du_b_vote"), 
                       measure=patterns("^voix", "^nom"), value.factor=FALSE, value.name = c("voix","nom")) %>% 
  .[, voix := sum(voix, na.rm = TRUE), by = c("code_de_la_commune", "code_du_b_vote", "nom")] %>%
  .[, variable := NULL]

head(resultatsVotes)
##    code_de_la_commune code_du_b_vote voix     nom
## 1:                  1           0001  356 ARTHAUD
## 2:                  2           0001  188 ARTHAUD
## 3:                  4           0001  161 ARTHAUD
## 4:                  4           0002   94 ARTHAUD
## 5:                  4           0003   54 ARTHAUD
## 6:                  4           0004   43 ARTHAUD

On calcule des indicateurs globaux de participation pour chaque bureau de vote.

statsBureaux <- cleaned_dt[, c("code_de_la_commune", "code_du_b_vote", "inscrits", "abstentions", "votants", "blancs", "nuls", "exprimes")] %>% 
  unique()

head(statsBureaux)
##    code_de_la_commune code_du_b_vote inscrits abstentions votants blancs nuls
## 1:                  1           0001      645         108     537     16    1
## 2:                  2           0001      213          38     175      3    1
## 3:                  4           0001     1129         266     863     18    5
## 4:                  4           0002     1128         265     863     15    6
## 5:                  4           0003     1213         246     967     10    8
## 6:                  4           0004      933         224     709      8    4
##    exprimes
## 1:      520
## 2:      171
## 3:      840
## 4:      842
## 5:      949
## 6:      697

Ce script est facilement modifiable si vous trouvez qu’il manque des infos dans les datasets finaux.

Pour l’utiliser avec les résultats du deuxième tour, l’url du jeu de données brut est la suivante : https://www.data.gouv.fr/fr/datasets/r/4dfd05a9-094e-4043-8a19-43b6b6bbe086.

Voir également