Ce document présente le détail des analyses réalisées autour de la question des liens entre orientations politiques et communes nouvelles. Les objectifs et résulats de l’étude sont présentés dans un document déposé sur HAL (https://cv.hal.science/gabriel-bideau). Ce script est un document de travail qui a pour but, dans une logique de science ouverte, de permettre la transparence, la vérification et la reproductibilité des analyses proposées.
Les données mises en forme seront rendues disponibles une fois l’article paru, sur la plateforme Nakala (les données initiales utilisées sont issues de la statistique publique et librement accessibles).
Ce travail s’inscrit dans le cadre d’une étude plus générale sur les communes nouvelles :
https://cv.hal.science/gabriel-bideau
Ne pas hésiter à contacter l’auteur (gabriel.bideau@gmail.com) pour toute question.
Lien vers une annexe en ligne, comportant les données et le détail du code : https://gbideau.github.io/CN_data/
Lien uniquement vers les résultats : https://gbideau.github.io/CN_elections/
Un problème majeur se pose en lien avec la géographie administrative à laquelle les résultats sont disponibles. En effet, les résultats des élections les plus facilement exploitables sont fournis à l’échelle communale, pour les communes existant lors de l’élection en question. Cela rend difficile l’étude des communes nouvelles qui, par définition, ont engendré des changements de périmètre. Par exemple, concernant les élections de 2017, les résultats sont disponibles à l’échelle des communes existant à cette date-là, ce qui empêche de réfléchir à l’homogénéité ou l’hétérogénéité interne aux communes nouvelles. En revanche, il est toujours possible d’agréger les données disponibles uniquement pour des communes n’ayant pas fusionné au périmètre de la future commune nouvelle.
Plusieurs possibilités ont été envisagées et deux ont été retenues :
Partir des données avant ou après la très grande majorité des fusions. En effet, les premières communes ont été créées en 2012 et les dernières, à l’heure où nous écrivons, au 1er janvier 2025. Cependant, leur nombre est peu important avant 2015 et après 2020. Ainsi, pour les élections précédant l’année 2014, le nombre de communes ayant fusionné étant tout à fait limité, nous avons les informations à l’échelle de la très grande majorité des communes fusionnantes. Pour les élections postérieures à l’année 2020, inversement, la très grande majorité des communes nouvelles existant aujourd’hui ont été créées, nous avons les informations pour la quasi totalité des communes nouvelles.
Pour les élections intermédiaires, nous utilisons les données à l’échelle des bureaux de vote pour reconstituer les données à l’échelle des communes fusionnantes. Cette solution est théoriquement la meilleure mais, dans la pratique, complexe à mettre en œuvre.
| Communes | Maille utilisée pour collecter les résultats des élections |
|---|---|
| Communes non concernées par les communes nouvelles | Données à l’échelle communale |
| Communes ayant fusionné après le scrutin concerné | Données à l’échelle communale |
| Communes ayant fusionné avant le scrutin concerné | Données à l’échelle des bureaux de vote (perte de quelques données) |
Pour le détail de la mise en œuvre, cf. le code ci-dessous.
# Import des données générales et socio-économiques
load("data/refdata.Rdata")
# load("Archives/data_prep 2011-2023(01)/data/refdata.Rdata")
# Import des géométries
geomfus2011 <- st_read("data/geom.gpkg", layer = "geomfus2011", quiet = TRUE) # Les communes qui ont participé à la création de communes nouvelles (appelées communes fusionnantes).
geom2011 <- st_read("data/geom.gpkg", layer = "geom2011", quiet = TRUE)
geomCN_new <- st_read("data/geom.gpkg", layer = "geomCN_new", quiet = TRUE)
geom_new <- st_read("data/geom.gpkg", layer = "geom_new", quiet = TRUE)
dep <- st_read("data/geom.gpkg", layer = "dep", quiet = TRUE) # Départements
Les données concernant les résultats des élections sont disponibles ici : https://www.data.gouv.fr/fr/pages/donnees-des-elections/
# Élection présidentielle 2012, tours 1 et 2, par communes
# https://www.data.gouv.fr/fr/datasets/election-presidentielle-2012-resultats-572126/
download.file("https://www.data.gouv.fr/fr/datasets/r/f81b2215-b297-4616-acbf-d8790ee38197", "data-raw/elections/2012_presidentielles_T1-T2_communes.xls")
# Élection présidentielle des 23 avril et 7 mai 2017 - Résultats définitifs du 1er tour par communes
# https://www.data.gouv.fr/fr/datasets/election-presidentielle-des-23-avril-et-7-mai-2017-resultats-definitifs-du-1er-tour-par-communes/
download.file("https://www.data.gouv.fr/fr/datasets/r/77ed6b2f-c48f-4037-8479-50af74fa5c7a", "data-raw/elections/2017_presidentielles_T1_communes.xls")
# Élection présidentielle des 23 avril et 7 mai 2017 - Résultats définitifs du 2nd tour par communes
# https://www.data.gouv.fr/fr/datasets/election-presidentielle-des-23-avril-et-7-mai-2017-resultats-definitifs-du-2nd-tour-par-communes/
download.file("https://www.data.gouv.fr/fr/datasets/r/be8faff4-dedf-44be-92c7-e77feb9df335", "data-raw/elections/2017_presidentielles_T2_communes.xls")
# Élection présidentielle des 10 et 24 avril 2022 - Résultats définitifs du 1er tour
# https://www.data.gouv.fr/fr/datasets/election-presidentielle-des-10-et-24-avril-2022-resultats-definitifs-du-1er-tour/
download.file("https://www.data.gouv.fr/fr/datasets/r/6d9b33e5-667d-4c3e-9a0b-5fdf5baac708", "data-raw/elections/2022_presidentielles_T1_communes.xlsx")
# Élection présidentielle des 10 et 24 avril 2022 - Résultats définitifs du 2nd tour
# https://www.data.gouv.fr/fr/datasets/election-presidentielle-des-10-et-24-avril-2022-resultats-definitifs-du-2nd-tour/
download.file("https://www.data.gouv.fr/fr/datasets/r/06d9816c-1b87-498d-985e-f312acee4f51", "data-raw/elections/2022_presidentielles_T2_communes.xlsx")
# Élections présidentielles de 2017, résultats par bureaux de vote
download.file("https://www.data.gouv.fr/fr/datasets/r/8fdb0926-ea9d-4fb4-a136-7767cd97e30b", "data-raw/elections/2017_presidentielles_T1_bureaux_de_vote.txt")
download.file("https://www.data.gouv.fr/fr/datasets/r/2e3e44de-e584-4aa2-8148-670daf5617e1", "data-raw/elections/2017_presidentielles_T2_bureaux_de_vote.txt")
# Élections présidentielles de 2022, résultats par bureaux de vote
# Élections présidentielles de 2017, premier tour, résultats par bureaux de vote
download.file("https://www.data.gouv.fr/fr/datasets/r/79b5cac4-4957-486b-bbda-322d80868224", "data-raw/elections/2022_presidentielles_T1_bureaux_de_vote.txt")
# Second tour : Données pas trouvées ici : https://www.data.gouv.fr/fr/datasets/election-presidentielle-des-10-et-24-avril-2022-resultats-du-second-tour/#/resources
# Elections européennes 2014 - Résultats par communes
# https://www.data.gouv.fr/fr/datasets/elections-europeennes-2014-resultats-par-communes/
download.file("https://www.data.gouv.fr/fr/datasets/r/d6817473-7c6b-4a41-955c-b620c86e7fd7", "data-raw/elections/2014_europeennes_communes.xlsx")
# Elections européennes 2019 - Résultats par communes
# https://www.data.gouv.fr/fr/datasets/resultats-des-elections-europeennes-2019/
download.file("https://www.data.gouv.fr/fr/datasets/r/cac2692c-67af-4bcb-9921-eca33e7f1ead", "data-raw/elections/2019_europeennes_communes.xls")
# Élections municipales 2014 - Résultats par communes
# https://www.data.gouv.fr/fr/pages/donnees-des-elections-et-referendums/
# Résultats 1er tour communes de moins de 1000 habitants
download.file("https://www.data.gouv.fr/storage/f/2014-03-25T16-08-50/muni-2014-resultats-com-moins-1000-t1.txt", "data-raw/elections/2014_municipales_T1_communes_moins1000.txt")
# Résultats 1er tour communes de 1000 habitants et plus
download.file("https://www.data.gouv.fr/storage/f/2014-03-25T16-06-23/muni-2014-resultats-com-1000-et-plus-t1.txt", "data-raw/elections/2014_municipales_T1_communes_plus1000.txt")
# Résultats 2nd tour communes de moins de 1000 habitants
download.file("https://www.data.gouv.fr/storage/f/2014-03-31T09-51-08/muni-2014-resultats-com-moins-1000-t2.txt", "data-raw/elections/2014_municipales_T2_communes_moins1000.txt")
# Résultats 2nd tour communes de 1000 habitants et plus
download.file("https://www.data.gouv.fr/storage/f/2014-03-31T09-49-28/muni-2014-resultats-com-1000-et-plus-t2.txt", "data-raw/elections/2014_municipales_T2_communes_plus1000.txt")
# Élections municipales 2020 - Résultats par communes
# https://www.data.gouv.fr/fr/pages/donnees-des-elections-et-referendums/
# Résultats 1er tour communes de moins de 1000 habitants
download.file("https://www.data.gouv.fr/fr/datasets/r/dacfcb29-7e58-4326-9d34-8ea7c5a9466c", "data-raw/elections/2020_municipales_T1_communes_moins1000.txt")
# Résultats 1er tour communes de 1000 habitants et plus
download.file("https://www.data.gouv.fr/fr/datasets/r/5129e7cf-2999-4eaf-8dd7-3bcda37bd0a3", "data-raw/elections/2020_municipales_T1_communes_plus1000.txt")
# Résultats 2nd tour communes de moins de 1000 habitants
download.file("https://www.data.gouv.fr/fr/datasets/r/7a5faf5f-7e3b-4de6-9f1d-a8e3ad176476", "data-raw/elections/2020_municipales_T2_communes_moins1000.txt")
# Résultats 2nd tour communes de 1000 habitants et plus
download.file("https://www.data.gouv.fr/fr/datasets/r/e7cae0aa-5e36-4370-b724-6f233014d0d6", "data-raw/elections/2020_municipales_T2_communes_plus1000.txt")
Pour créer une commune nouvelle, le pouvoir décisionnaire appartient aux conseillères et conseillers municipaux. Pour étudier le positionnement politique des communes nouvelles, le mieux serait donc d’avoir des données concernant les nuances politiques associées aux personnes ayant remporté les élections municipales. Les préfectures associent bien des nuances politiques à chaque candidat et candidate aux élections législatives par exemple, mais cela n’est réalisé que pour les communes de plus de 1000 habitants aux élections municipales. Or, les communes de moins de 1000 habitants représentent plus de 77% des communes fusionnantes.
Si on s’intéresse, néanmoins aux communes de plus de 1000 habitants (code présent plus bas mais non joué dans le knit), on observe déjà une présence non négligeable de nuances peu exploitables comme “LDIV”, signifiant “Listes divers”. D’autre part, puisqu’un des objectifs est d’observer l’homogénéité ou l’hétérogénéité des constitutions des communes nouvelles, il faudrait qu’on dispose d’un nombre représentatif de communes nouvelles créées avec des communes ayant majoritairement plus de 1000 habitants, ce qui n’est pas le cas, cette option n’est donc pas utilisable.
À titre d’exemple si on regarde les quelques données dont on dispose (communes de plus de 999 habitants, soit environ 700 communes), les rares communes qui sont homogènes (et qui regroupent donc des communes dont on connaît la nuance) sont plus fréquemment des communes où ce sont des listes “Divers droite” qui l’ont emporté. Sur-représentation car elles représentent 40% des communes fusionnantes et 61% des communes nouvelles homogènes (mais à peine 1% des communes nouvelles).
Munic2014T1moins1000 <- read.table("data-raw/elections/2014_municipales_T1_communes_moins1000.txt", head = FALSE, sep = ";", stringsAsFactors = FALSE, fileEncoding = "latin1", fill = TRUE, quote="\"")
# Ne permet pas d'avoir d'informations sur la nuance politique
Munic2014T2moins1000 <- read.table("data-raw/elections/2014_municipales_T2_communes_moins1000.txt", head = FALSE, sep = ";", stringsAsFactors = FALSE, fileEncoding = "latin1", fill = TRUE, quote="\"")
colnames(Munic2014T2moins1000) <- Munic2014T2moins1000[1,]
table(Munic2014T2moins1000$`Code Nuance`)
# Ne permet pas d'avoir d'informations sur la nuance politique
ncol <- max(count.fields("data-raw/elections/2014_municipales_T1_communes_plus1000.txt", sep = ";"), na.rm = TRUE)
# Nombre de colonne absolument énorme mais c'est effectivement ce qui est nécessaire
Munic2014T1plus1000 <- read.table("data-raw/elections/2014_municipales_T1_communes_plus1000.txt", head = FALSE, sep = ";", stringsAsFactors = FALSE, fileEncoding = "latin1", fill = TRUE, quote="\"", col.names = paste0("V", seq_len(ncol)))
ncol <- max(count.fields("data-raw/elections/2014_municipales_T2_communes_plus1000.txt", sep = ";"), na.rm = TRUE)
Munic2014T2plus1000 <- read.table("data-raw/elections/2014_municipales_T2_communes_plus1000.txt", head = FALSE, sep = ";", stringsAsFactors = FALSE, fileEncoding = "latin1", fill = TRUE, quote="\"", col.names = paste0("V", seq_len(ncol)))
# On préfère utiliser des fichiers modifiés manuellement pour retirer l'outre-mer (induit un nombre de colonnes trop important)
ncol <- max(count.fields("data-raw/elections/2014_municipales_T1_communes_plus1000_sansOM.txt", sep = ";"), na.rm = TRUE)
Munic2014T1plus1000 <- read.table("data-raw/elections/2014_municipales_T1_communes_plus1000_sansOM.txt", head = FALSE, sep = ";", stringsAsFactors = FALSE, fileEncoding = "latin1", fill = TRUE, quote="\"", col.names = paste0("V", seq_len(ncol)))
ncol <- max(count.fields("data-raw/elections/2014_municipales_T2_communes_plus1000_sansOM.txt", sep = ";"), na.rm = TRUE)
Munic2014T2plus1000 <- read.table("data-raw/elections/2014_municipales_T2_communes_plus1000_sansOM.txt", head = FALSE, sep = ";", stringsAsFactors = FALSE, fileEncoding = "latin1", fill = TRUE, quote="\"", col.names = paste0("V", seq_len(ncol)))
Munic2020T1moins1000 <- read.table("data-raw/elections/2020_municipales_T1_communes_moins1000.txt", head = FALSE, sep = ";", stringsAsFactors = FALSE, fileEncoding = "latin1", fill = TRUE, quote="\"")
# Ne permet pas d'avoir d'informations sur la nuance politique
Munic2020T2moins1000 <- read.table("data-raw/elections/2020_municipales_T2_communes_moins1000.txt", head = FALSE, sep = ";", stringsAsFactors = FALSE, fileEncoding = "latin1", fill = TRUE, quote="\"")
colnames(Munic2020T2moins1000) <- Munic2020T2moins1000[1,]
table(Munic2020T2moins1000$`Code Nuance`)
# Ne permet pas d'avoir d'informations sur la nuance politique
ncol <- max(count.fields("data-raw/elections/2020_municipales_T1_communes_plus1000.txt", sep = "\t"), na.rm = TRUE)
# Nombre de colonne absolument énorme mais c'est effectivement ce qui est nécessaire
Munic2020T1plus1000 <- read.table("data-raw/elections/2020_municipales_T1_communes_plus1000.txt", head = FALSE, sep = "\t", stringsAsFactors = FALSE, fileEncoding = "latin1", fill = TRUE, skip = 0, quote="\"", col.names = paste0("V", seq_len(ncol)))
ncol <- max(count.fields("data-raw/elections/2020_municipales_T2_communes_plus1000.txt", sep = ";"), na.rm = TRUE)
Munic2020T2plus1000 <- read.table("data-raw/elections/2020_municipales_T2_communes_plus1000.txt", head = FALSE, sep = ";", stringsAsFactors = FALSE, fileEncoding = "latin1", fill = TRUE, quote="\"", col.names = paste0("V", seq_len(ncol)))
# On supprime l'outre-mer
departements_pour_OM <- as.data.frame(table(Munic2020T1plus1000[,1]))
Munic2020T1plus1000 <- subset(Munic2020T1plus1000, Munic2020T1plus1000$V1 != "ZA" &
Munic2020T1plus1000$V1 != "ZB" &
Munic2020T1plus1000$V1 != "ZD" &
Munic2020T1plus1000$V1 != "ZM" &
Munic2020T1plus1000$V1 != "ZN" &
Munic2020T1plus1000$V1 != "ZC" &
Munic2020T1plus1000$V1 != "ZP" &
Munic2020T1plus1000$V1 != "ZS")
# departements_pour_OM <- as.data.frame(table(Munic2020T2plus1000[,1]))
Munic2020T2plus1000 <- subset(Munic2020T2plus1000, Munic2020T2plus1000$V1 != "ZA" &
Munic2020T2plus1000$V1 != "ZB" &
Munic2020T2plus1000$V1 != "ZC" &
Munic2020T2plus1000$V1 != "ZD" &
Munic2020T2plus1000$V1 != "ZM" &
Munic2020T2plus1000$V1 != "ZN" &
Munic2020T2plus1000$V1 != "ZP")
# On regarde le nombre de colonnes avec des valeurs vides pour toutes les lignes désormais
test <- data.frame(apply(Munic2020T1plus1000, MARGIN = 2, function(x){sum(is.na(x))}))
apply(Munic2020T2plus1000, MARGIN = 2, function(x){sum(is.na(x))})
# Beaucoup de colonnes majoritairement vides mais peu de colonnes complètement vides. Donc on laisse les données ainsi.
# === DONNÉES PREMIER TOUR ===
# Récupération des noms de colonnes
colnames(Munic2014T1plus1000) <- Munic2014T1plus1000[1,]
Munic2014T1plus1000 <- Munic2014T1plus1000[-1,]
# Les noms des colonnes sont inexploitables
colnames(Munic2014T1plus1000)
# Municip2014T1Cfus_sauv <- Municip2014T1Cfus
# Municip2014T1Cfus <- Municip2014T1Cfus_sauv
# Création d'un vecteur destiné à remplacer le nom des colonnes
# D'abord en répétant, avec un indicateur distinctif, les indications des colonnes spécifiques à chaque liste
colonnes_listes <- paste0(colnames(Munic2014T1plus1000)[18:28], rep(1:12, each = 11))
# Puis en concaténant avec les données précédentes
colonnes_tableau <- c(colnames(Munic2014T1plus1000)[1:17], colonnes_listes, paste0("colNA", 1:6))
# Puis on assigne au tableau
colnames(Munic2014T1plus1000) <- colonnes_tableau
colnames(Munic2014T1plus1000)
# Création d'un champ CODGEO permettant la jonction des tables
Munic2014T1plus1000$CODGEO <- paste0(Munic2014T1plus1000$`Code du département`, Munic2014T1plus1000$`Code de la commune`)
# === DONNÉES SECOND TOUR ===
# Récupération des noms de colonnes
colnames(Munic2014T2plus1000) <- Munic2014T2plus1000[1,]
Munic2014T2plus1000 <- Munic2014T2plus1000[-1,]
# Les noms des colonnes sont inexploitables
colnames(Munic2014T2plus1000)
# Municip2014T1Cfus_sauv <- Municip2014T1Cfus
# Municip2014T1Cfus <- Municip2014T1Cfus_sauv
# Création d'un vecteur destiné à remplacer le nom des colonnes
# D'abord en répétant, avec un indicateur distinctif, les indications des colonnes spécifiques à chaque liste
colonnes_listes <- paste0(colnames(Munic2014T2plus1000)[18:28], rep(1:15, each = 11))
# Puis en concaténant avec les données précédentes
colonnes_tableau <- c(colnames(Munic2014T2plus1000)[1:17], colonnes_listes, paste0("colNA", 1:10))
# Puis on assigne au tableau
colnames(Munic2014T2plus1000) <- colonnes_tableau
colnames(Munic2014T2plus1000)
# Création d'un champ CODGEO permettant la jonction des tables
Munic2014T2plus1000$CODGEO <- paste0(Munic2014T2plus1000$`Code du département`, Munic2014T2plus1000$`Code de la commune`)
# On veut déterminer la nuance politique de la liste ayant remportée les élections municipales
# Pour cela, il faut travailler sur les fichiers du 1er et du 2e tour (puisqu'une liste peut l'avoir emporté au 1er tour mais que la commune est néanmoins renseignée si personne n'a gagné)
# Liste des colonnes mentionnant les sièges/élus
liste_col_elus_T1 <- c(grep(pattern = "Sièges / Elu", colnames(Munic2014T1plus1000), ignore.case = FALSE))
liste_col_elus_T2 <- c(grep(pattern = "Sièges / Elu", colnames(Munic2014T2plus1000), ignore.case = FALSE))
# On passe les données en question en variables numériques
Munic2014T1plus1000[liste_col_elus_T1 ] <- lapply(Munic2014T1plus1000[liste_col_elus_T1], as.numeric)
Munic2014T2plus1000[liste_col_elus_T2 ] <- lapply(Munic2014T2plus1000[liste_col_elus_T2], as.numeric)
results <- data.frame()
Code_Comm <- "01034"
# Pour chaque commune du tableau Munic2014T1plus1000 (il faut partir des communes de 1000 habitants ou plus)
for (Code_Comm in Munic2014T1plus1000$CODGEO) {
# On crée un tableau spécifique
Tour1 <- subset(Munic2014T1plus1000, Munic2014T1plus1000$CODGEO == Code_Comm)
# On relève le nom de la commune pour faciliter la lecture des résultats intermédiaires
Nom_Comm <- Tour1$`Libellé de la commune`
# Si la somme des sièges attribués au 1er tour est non nulle
if (sum(Tour1[, liste_col_elus_T1], na.rm = TRUE) != 0) {
# On recherche la colonne indiquant une nuance politique ayant la plus grande valeur
Tour1$Liste_vict <- colnames(Tour1[, liste_col_elus_T1])[as.numeric(apply(Tour1[, liste_col_elus_T1], 1, which.max))]
# On recherche désormais la valeur de la colonne indiquant la nuance de la liste ayant eu le plus grand nombre d'élus et on y ajoute l'identifiction de la colonne Code Nuance
Tour1$NumListe_vict <- paste0("Code Nuance", substr(Tour1$Liste_vict, start = 13, stop = 13))
# On sauvegarde la valeur de cette nuance politique
NuanceVict <- Tour1[,Tour1$NumListe_vict]
# On concatène les résultats
result <- c(Code_Comm, Nom_Comm, NuanceVict)
results <- rbind(results, result, stringsAsFactors= FALSE) # Combiner les résultats, par lignes
# On joint le tableau des résultats avec celui de
} else { # Sinon on va chercher le résultat dans le tableau du 2e tour
# On crée un tableau spécifique
Tour2 <- subset(Munic2014T2plus1000, Munic2014T2plus1000$CODGEO == Code_Comm)
# On recherche la colonne indiquant une nuance politique ayant la plus grande valeur
Liste_vict <- colnames(Tour2[, liste_col_elus_T2])[as.numeric(apply(Tour2[, liste_col_elus_T2], 1, which.max))]
# On recherche désormais la valeur de la colonne indiquant la nuance de la liste ayant eu le plus grand nombre d'élus et on y ajoute l'identifiction de la colonne Code Nuance
NumListe_vict <- paste0("Code Nuance", substr(Liste_vict, start = 13, stop = 13))
# On sauvegarde la valeur de cette nuance politique
NuanceVict <- Tour2[,NumListe_vict]
# On concatène les résultats
result <- c(Code_Comm, Nom_Comm, NuanceVict)
results <- rbind(results,result, stringsAsFactors= FALSE) # Combiner les résultats, par lignes
}
}
colnames(results) <- c("CODGEO", "Nom_data_elections", "NuanceVictorieuse")
table(results$NuanceVictorieuse)
test <- subset(Munic2014T1plus1000, Munic2014T1plus1000$CODGEO == "01034")
test <- subset(Munic2014T2plus1000, Munic2014T2plus1000$CODGEO == "01034")
# Tentative sur l'ensemble du tableau en même temps mais bloque à la dernière étape, d'où le choix de fontionner par boucle
# # On liste le nombre d'élus au premier tour
# Munic2014T1plus1000$Elus <- apply(Munic2014T1plus1000[, liste_col_elus_T1], 1, function(x) sum(x, na.rm = TRUE))
# # Et si, du coup, la liste a été élue au premier tour
# Munic2014T1plus1000$Elect1Tour <- if_else(Munic2014T1plus1000$Elus!= 0, "OUI", "NON")
# # On recherche la colonne indiquant le nombre d'élus ayant la plus grande valeur
# Munic2014T1plus1000$Liste_vict <- colnames(Munic2014T1plus1000[, liste_col_elus_T1])[as.numeric(apply(Munic2014T1plus1000[, liste_col_elus_T1], 1, which.max))]
# # On recherche désormais la valeur de la colonne indiquant la nuance de la liste ayant eu le plus grand nombre d'élus et on y ajoute l'identifiction de la colonne Code Nuance
# Munic2014T1plus1000$NumListe_vict <- paste0("Code Nuance", substr(Munic2014T1plus1000$Liste_vict, start = 13, stop = 13))
# Munic2014T1plus1000$NuanceListe_vict <- Munic2014T1plus1000[Munic2014T1plus1000$NumListe_vict]
# # On indique la valeur de la colonne qu'on a identifié
# ## Ne fonctionne pas
# Munic2014T1plus1000$NuanceListe_vict <- apply(Munic2014T1plus1000, 1, Munic2014T1plus1000[Munic2014T1plus1000$NumListe_vict])
# === DONNÉES PREMIER TOUR ===
# Récupération des noms de colonnes
colnames(Munic2020T1plus1000) <- Munic2020T1plus1000[1,]
Munic2020T1plus1000 <- Munic2020T1plus1000[-1,]
# Les noms des colonnes sont inexploitables
colnames(Munic2020T1plus1000)
# Municip2020T1Cfus_sauv <- Municip2020T1Cfus
# Municip2020T1Cfus <- Municip2020T1Cfus_sauv
# Création d'un vecteur destiné à remplacer le nom des colonnes
# D'abord en répétant, avec un indicateur distinctif, les indications des colonnes spécifiques à chaque liste
colonnes_listes <- paste0(colnames(Munic2020T1plus1000)[18:28], rep(1:55, each = 11))
# Puis en concaténant avec les données précédentes
colonnes_tableau <- c(colnames(Munic2020T1plus1000)[1:17], colonnes_listes, paste0("colNA", 1:4))
# Puis on assigne au tableau
colnames(Munic2020T1plus1000) <- colonnes_tableau
colnames(Munic2020T1plus1000)
# On rajoute des zéros (0) aux variables département et numéro de commune pour créer un identifiant CODGEO
Munic2020T1plus1000$`Code de la commune` <- str_pad(Munic2020T1plus1000$`Code de la commune`, 3, pad = "0") # Si besoin de rajouter des zéros
Munic2020T1plus1000$`Code du département` <- str_pad(Munic2020T1plus1000$`Code du département`, 2, pad = "0")
# Création d'un champ CODGEO permettant la jonction des tables
Munic2020T1plus1000$CODGEO <- paste0(Munic2020T1plus1000$`Code du département`, Munic2020T1plus1000$`Code de la commune`)
# === DONNÉES SECOND TOUR ===
# Récupération des noms de colonnes
colnames(Munic2020T2plus1000) <- Munic2020T2plus1000[1,]
Munic2020T2plus1000 <- Munic2020T2plus1000[-1,]
# Les noms des colonnes sont inexploitables
colnames(Munic2020T2plus1000)
# Municip2020T1Cfus_sauv <- Municip2020T1Cfus
# Municip2020T1Cfus <- Municip2020T1Cfus_sauv
# Création d'un vecteur destiné à remplacer le nom des colonnes
# D'abord en répétant, avec un indicateur distinctif, les indications des colonnes spécifiques à chaque liste
colonnes_listes <- paste0(colnames(Munic2020T2plus1000)[18:28], rep(1:11, each = 11))
# Puis en concaténant avec les données précédentes
colonnes_tableau <- c(colnames(Munic2020T2plus1000)[1:17], colonnes_listes, paste0("colNA", 1:8))
# Puis on assigne au tableau
colnames(Munic2020T2plus1000) <- colonnes_tableau
colnames(Munic2020T2plus1000)
# On rajoute des zéros (0) aux variables département et numéro de commune pour créer un identifiant CODGEO
Munic2020T2plus1000$`Code de la commune` <- str_pad(Munic2020T2plus1000$`Code de la commune`, 3, pad = "0") # Si besoin de rajouter des zéros
Munic2020T2plus1000$`Code du département` <- str_pad(Munic2020T2plus1000$`Code du département`, 2, pad = "0")
# Création d'un champ CODGEO permettant la jonction des tables
Munic2020T2plus1000$CODGEO <- paste0(Munic2020T2plus1000$`Code du département`, Munic2020T2plus1000$`Code de la commune`)
# On veut déterminer la nuance politique de la liste ayant remportée les élections municipales
# Pour cela, il faut travailler sur les fichiers du 1er et du 2e tour (puisqu'une liste peut l'avoir emporté au 1er tour mais que la commune est néanmoins renseignée si personne n'a gagné)
# Liste des colonnes mentionnant les sièges/élus
liste_col_elus_T1 <- c(grep(pattern = "Sièges / Elu", colnames(Munic2020T1plus1000), ignore.case = FALSE))
liste_col_elus_T2 <- c(grep(pattern = "Sièges / Elu", colnames(Munic2020T2plus1000), ignore.case = FALSE))
# On passe les données en question en variables numériques
Munic2020T1plus1000[liste_col_elus_T1 ] <- lapply(Munic2020T1plus1000[liste_col_elus_T1], as.numeric)
Munic2020T2plus1000[liste_col_elus_T2 ] <- lapply(Munic2020T2plus1000[liste_col_elus_T2], as.numeric)
# Certaines communes posent problèmes, sans que je ne comprenne bien pourquoi. Comme l'analyse des nuances n'est pour l'instant pas l'objectif, on supprime les données problématiques
communes_a_etudier <- c(Munic2020T1plus1000$CODGEO)
which(communes_a_etudier == "02408")
communes_a_etudier <- communes_a_etudier[-230]
# En raccourci pour les suivantes
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "06023")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "06029")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "07255")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "08142")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "11418")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "13063")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "13092")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "19031")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "21425")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "24229")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "24436")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "29016")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "29062")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "30019")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "30278")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "31033")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "31157")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "33243")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "35068")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "36088")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "37122")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "38162")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "44043")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "44155")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "46029")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "49353")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "51230")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "56260")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "59133")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "59172")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "59183")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "60057")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "60409")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "60685")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "62193")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "62200")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "62351")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "62413")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "62563")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "64035")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "67326")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "67447")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "69034")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "69290")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "71073")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "71153")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "72124")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "72143")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "73011")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "74167")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "76222")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "76499")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "76545")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "77075")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "77135")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "77168")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "77333")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "77419")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "77513")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "78172")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "79285")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "80182")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "83093")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "84092")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "84142")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "89100")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "89130")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "80716")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "81289")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "83057")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "91657")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "92007")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "92036")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "93007")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "93027")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "94033")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "94046")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "95580")]
communes_a_etudier <- communes_a_etudier[-which(communes_a_etudier == "95680")]
# Si nécessaire de supprimer des données
# communes_a_etudier <- communes_a_etudier[130:length(communes_a_etudier)]
results <- data.frame()
# Code_Comm <- "02408"
# Pour chaque commune du tableau Munic2020T1plus1000 (il faut partir des communes de 1000 habitants ou plus)
# for (Code_Comm in Munic2020T1plus1000$CODGEO) {
for (Code_Comm in communes_a_etudier) {
# On crée un tableau spécifique
Tour1 <- subset(Munic2020T1plus1000, Munic2020T1plus1000$CODGEO == Code_Comm)
# On relève le nom de la commune pour faciliter la lecture des résultats intermédiaires
Nom_Comm <- Tour1$`Libellé de la commune`
# Si la somme des sièges attribués au 1er tour est non nulle
if (sum(Tour1[, liste_col_elus_T1], na.rm = TRUE) != 0) {
# On recherche la colonne indiquant une nuance politique ayant la plus grande valeur
Tour1$Liste_vict <- colnames(Tour1[, liste_col_elus_T1])[as.numeric(apply(Tour1[, liste_col_elus_T1], 1, which.max))]
# On recherche désormais la valeur de la colonne indiquant la nuance de la liste ayant eu le plus grand nombre d'élus et on y ajoute l'identifiction de la colonne Code Nuance
Tour1$NumListe_vict <- paste0("Code Nuance", substr(Tour1$Liste_vict, start = 13, stop = 13))
# On sauvegarde la valeur de cette nuance politique
NuanceVict <- Tour1[,Tour1$NumListe_vict]
# On concatène les résultats
result <- c(Code_Comm, Nom_Comm, NuanceVict)
results <- rbind(results, result, stringsAsFactors= FALSE) # Combiner les résultats, par lignes
# On joint le tableau des résultats avec celui de
} else { # Sinon on va chercher le résultat dans le tableau du 2e tour
# On crée un tableau spécifique
Tour2 <- subset(Munic2020T2plus1000, Munic2020T2plus1000$CODGEO == Code_Comm)
# On recherche la colonne indiquant une nuance politique ayant la plus grande valeur
Liste_vict <- colnames(Tour2[, liste_col_elus_T2])[as.numeric(apply(Tour2[, liste_col_elus_T2], 1, which.max))]
# On recherche désormais la valeur de la colonne indiquant la nuance de la liste ayant eu le plus grand nombre d'élus et on y ajoute l'identifiction de la colonne Code Nuance
NumListe_vict <- paste0("Code Nuance", substr(Liste_vict, start = 13, stop = 13))
# On sauvegarde la valeur de cette nuance politique
NuanceVict <- Tour2[,NumListe_vict]
# On concatène les résultats
result <- c(Code_Comm, Nom_Comm, NuanceVict)
results <- rbind(results,result, stringsAsFactors= FALSE) # Combiner les résultats, par lignes
}
}
colnames(results) <- c("CODGEO", "Nom_data_elections", "NuanceVictorieuse")
table(results$NuanceVictorieuse)
test <- subset(Munic2020T1plus1000, Munic2020T1plus1000$CODGEO == "01034")
test <- subset(Munic2020T2plus1000, Munic2020T2plus1000$CODGEO == "01034")
# Tentative sur l'ensemble du tableau en même temps mais bloque à la dernière étape, d'où le choix de fontionner par boucle
# # On liste le nombre d'élus au premier tour
# Munic2020T1plus1000$Elus <- apply(Munic2020T1plus1000[, liste_col_elus_T1], 1, function(x) sum(x, na.rm = TRUE))
# # Et si, du coup, la liste a été élue au premier tour
# Munic2020T1plus1000$Elect1Tour <- if_else(Munic2020T1plus1000$Elus!= 0, "OUI", "NON")
# # On recherche la colonne indiquant le nombre d'élus ayant la plus grande valeur
# Munic2020T1plus1000$Liste_vict <- colnames(Munic2020T1plus1000[, liste_col_elus_T1])[as.numeric(apply(Munic2020T1plus1000[, liste_col_elus_T1], 1, which.max))]
# # On recherche désormais la valeur de la colonne indiquant la nuance de la liste ayant eu le plus grand nombre d'élus et on y ajoute l'identifiction de la colonne Code Nuance
# Munic2020T1plus1000$NumListe_vict <- paste0("Code Nuance", substr(Munic2020T1plus1000$Liste_vict, start = 13, stop = 13))
# Munic2020T1plus1000$NuanceListe_vict <- Munic2020T1plus1000[Munic2020T1plus1000$NumListe_vict]
# # On indique la valeur de la colonne qu'on a identifié
# ## Ne fonctionne pas
# Munic2020T1plus1000$NuanceListe_vict <- apply(Munic2020T1plus1000, 1, Munic2020T1plus1000[Munic2020T1plus1000$NumListe_vict])
Sur les conseils de Jean Rivière, on s’intéresse aux résultats des élections sous le prisme de l’abstention, au 1er tour en 2014 puis 2020.
# Jouer en ayant simplement fait l'import des données brutes
# On indique les intitulés des colonnes
colnames(Munic2014T1moins1000) <- Munic2014T1moins1000[1,]
Munic2014T1moins1000 <- Munic2014T1moins1000[-1,] # On supprime la liste avec les intitulés des colonnes
# On supprime l'outre-mer
Munic2014T1moins1000 <- subset(Munic2014T1moins1000, Munic2014T1moins1000$CODDPT != "ZB" &
Munic2014T1moins1000$CODDPT != "ZC" &
Munic2014T1moins1000$CODDPT != "ZP" &
Munic2014T1moins1000$CODDPT != "ZS")
# On crée un identifiant CODGEO
Munic2014T1moins1000$CODGEO <- paste0(Munic2014T1moins1000$CODDPT, Munic2014T1moins1000$CODSUBCOM)
# On supprime les doublons
Munic2014T1moins1000 <- Munic2014T1moins1000[-which(duplicated(Munic2014T1moins1000$CODGEO)),]
# On se concentre sur certaines données qui nous intéressent
Munic2014T1moins1000 <- Munic2014T1moins1000[, c("CODGEO", "LIBSUBCOM", "NBRINS", "NBRABS", "NBREXP", "PCTVOTINS", "PCTABSINS", "PCTEXPINS")]
Munic2014T1moins1000$type_comm <- "moins_1000"
# Communes de plus de 1000 habitants
# On indique les intitulés des colonnes
colnames(Munic2014T1plus1000) <- Munic2014T1plus1000[1,]
Munic2014T1plus1000 <- Munic2014T1plus1000[-1,] # On supprime la liste avec les intitulés des colonnes
# On crée un identifiant CODGEO
Munic2014T1plus1000$CODGEO <- paste0(Munic2014T1plus1000$`Code du département`, Munic2014T1plus1000$`Code de la commune`)
# On se concentre sur certaines données qui nous intéressent
Munic2014T1plus1000 <- Munic2014T1plus1000[, c("CODGEO", "Libellé de la commune", "Inscrits", "Abstentions", "Exprimés", "% Vot/Ins", "% Abs/Ins", "% Exp/Ins")]
colnames(Munic2014T1plus1000) <- c("CODGEO", "LIBSUBCOM", "NBRINS", "NBRABS", "NBREXP", "PCTVOTINS", "PCTABSINS", "PCTEXPINS")
Munic2014T1plus1000$type_comm <- "1000_et_plus"
Munic2014T1 <- rbind(Munic2014T1moins1000, Munic2014T1plus1000)
# On indique les intitulés des colonnes
colnames(Munic2020T1moins1000) <- Munic2020T1moins1000[1,]
Munic2020T1moins1000 <- Munic2020T1moins1000[-1,] # On supprime la liste avec les intitulés des colonnes
table(Munic2020T1moins1000$`Code du département`)
# Permet de voir qu'il y a deux enregistrements qui posent problème, sans doute une ligne qui se coupe alors qu'elle ne devrait pas.
test <- subset(Munic2020T1moins1000, Munic2020T1moins1000$`Libellé de la commune` == "Labalme")
# On supprime l'outre-mer et la Corse
Munic2020T1moins1000 <- subset(Munic2020T1moins1000, Munic2020T1moins1000$`Code du département` != "ZB" &
Munic2020T1moins1000$`Code du département` != "ZC" &
Munic2020T1moins1000$`Code du département` != "ZN" &
Munic2020T1moins1000$`Code du département` != "ZP" &
Munic2020T1moins1000$`Code du département` != "2A" &
Munic2020T1moins1000$`Code du département` != "2B")
# On crée un identifiant CODGEO
Munic2020T1moins1000$CODGEO <- paste0(Munic2020T1moins1000$`Code du département`, Munic2020T1moins1000$`Code de la commune`)
# On supprime les doublons, qui sont visiblement des problèmes de lecture (ou d'écriture) du tableau, n'ayant pas d'impact sur l'étude de la participation
# doublons <- Munic2020T1moins1000[which(duplicated(Munic2020T1moins1000$CODGEO)),]
Munic2020T1moins1000 <- Munic2020T1moins1000[-which(duplicated2(Munic2020T1moins1000$CODGEO)),]
# On se concentre sur certaines données qui nous intéressent
Munic2020T1moins1000 <- Munic2020T1moins1000[, c("CODGEO", "Libellé de la commune", "Inscrits", "Abstentions", "Exprimés", "% Vot/Ins", "% Abs/Ins", "% Exp/Ins")]
colnames(Munic2020T1moins1000) <- c("CODGEO", "LIBSUBCOM", "NBRINS", "NBRABS", "NBREXP", "PCTVOTINS", "PCTABSINS", "PCTEXPINS")
sapply(Munic2020T1moins1000, class)
# Pose problème du fait du symbole de décimale
# Munic2020T1moins1000[3:8] <- lapply(Munic2020T1moins1000[3:8], as.numeric)
# colnames(Munic2020T1moins1000)
Munic2020T1moins1000$type_comm <- "moins_1000"
# Données des communes de plus de 1000 habitants
# On indique les intitulés des colonnes
colnames(Munic2020T1plus1000) <- Munic2020T1plus1000[1,]
Munic2020T1plus1000 <- Munic2020T1plus1000[-1,] # On supprime la liste avec les intitulés des colonnes
# On crée un identifiant CODGEO
Munic2020T1plus1000$CODGEO <- paste0(Munic2020T1plus1000$`Code du département`, Munic2020T1plus1000$`Code de la commune`)
# On se concentre sur certaines données qui nous intéressent
Munic2020T1plus1000 <- Munic2020T1plus1000[, c("CODGEO", "Libellé de la commune", "Inscrits", "Abstentions", "Exprimés", "% Vot/Ins", "% Abs/Ins", "% Exp/Ins")]
colnames(Munic2020T1plus1000) <- c("CODGEO", "LIBSUBCOM", "NBRINS", "NBRABS", "NBREXP", "PCTVOTINS", "PCTABSINS", "PCTEXPINS")
sapply(Munic2020T1plus1000, class)
# Munic2020T1plus1000[3:8] <- lapply(Munic2020T1plus1000[3:8], as.numeric)
Munic2020T1plus1000$type_comm <- "1000_et_plus"
Munic2020T1 <- rbind(Munic2020T1moins1000, Munic2020T1plus1000)
# On supprime quelques valeurs problématiques
Munic2020T1 <- subset(Munic2020T1, nchar(Munic2020T1$CODGEO) == 5)
# Sauvegarde des résultats 2014
write.table(results, "data/elections/Municipales2014_NuanceVictorieuse.csv", sep="\t", dec = ",", row.names=FALSE)
# Code pour importer les résultats concernant la nuance politique victorieuse aux élections municipales de 2014
NuanceMunicip2014 <- read.table("data/elections/Municipales2014_NuanceVictorieuse.csv", sep="\t", colClasses = "character", head = TRUE, stringsAsFactors = TRUE)
write.table(Munic2014T1plus1000, "data/elections/Municipales2014_T1_plus1000.csv", sep="\t", dec = ",", row.names=FALSE)
Munic2014T1plus1000 <- read.table("data/elections/Municipales2014_T1_plus1000.csv", sep="\t", colClasses = "character", head = TRUE, stringsAsFactors = TRUE)
write.table(Munic2014T2plus1000, "data/elections/Municipales2014_T2_plus1000.csv", sep="\t", dec = ",", row.names=FALSE)
Munic2014T2plus1000 <- read.table("data/elections/Municipales2014_T2_plus1000.csv", sep="\t", colClasses = "character", head = TRUE, stringsAsFactors = TRUE)
# Attention, travail que de la participation et de l'abstention
write.table(Munic2014T1, "data/elections/Municipales2014_T1_abstention.csv", sep="\t", dec = ",", row.names=FALSE)
Munic2014T1 <- read.table("data/elections/Municipales2014_T1_abstention.csv", sep="\t", colClasses = "character", head = TRUE, stringsAsFactors = TRUE)
# Sauvegarde des résultats 2020
write.table(results, "data/elections/Municipales2020_NuanceVictorieuse.csv", sep="\t", dec = ",", row.names=FALSE)
# Code pour importer les résultats concernant la nuance politique victorieuse aux élections municipales de 2020
NuanceMunicip2020 <- read.table("data/elections/Municipales2020_NuanceVictorieuse.csv", sep="\t", colClasses = "character", head = TRUE, stringsAsFactors = TRUE)
write.table(Munic2020T1plus1000, "data/elections/Municipales2020_T1_plus1000.csv", sep="\t", dec = ",", row.names=FALSE)
Munic2020T1plus1000 <- read.table("data/elections/Municipales2020_T1_plus1000.csv", sep="\t", colClasses = "character", head = TRUE, stringsAsFactors = TRUE)
write.table(Munic2020T2plus1000, "data/elections/Municipales2020_T2_plus1000.csv", sep="\t", dec = ",", row.names=FALSE)
Munic2020T2plus1000 <- read.table("data/elections/Municipales2020_T2_plus1000.csv", sep="\t", colClasses = "character", head = TRUE, stringsAsFactors = TRUE)
write.table(Munic2020T1, "data/elections/Municipales2020_T1_abstention.csv", sep="\t", dec = ",", row.names=FALSE)
Munic2020T1 <- read.table("data/elections/Municipales2020_T1_abstention.csv", sep="\t", colClasses = "character", head = TRUE, stringsAsFactors = TRUE)
Munic2020T1 <- read.table("data/elections/Municipales2020_T1_abstention.csv", sep="\t",
head = TRUE, stringsAsFactors = TRUE)
# Import des données nécessaires
NuanceMunicip2014 <- read.table("data/elections/Municipales2014_NuanceVictorieuse.csv", sep="\t", colClasses = "character", head = TRUE, stringsAsFactors = TRUE)
Munic2014T1plus1000 <- read.table("data/elections/Municipales2014_T1_plus1000.csv", sep="\t", colClasses = "character", head = TRUE, stringsAsFactors = TRUE, encoding="UTF-8")
Munic2014T2plus1000 <- read.table("data/elections/Municipales2014_T2_plus1000.csv", sep="\t", colClasses = "character", head = TRUE, stringsAsFactors = TRUE)
# On fait une boucle pour enlever retrouver les noms de colonnes initiaux. Sans doute que cela peut être fait plus proprement mais là au moins cela fonctionne
result <- c()
# i <- colnames(Munic2014T1plus1000)[105]
for (i in colnames(Munic2014T1plus1000)) {
i <- str_replace_all(i, "X\\.", "%")
i <- str_replace_all(i, "\\.", " ")
result <- c(result, i)
}
colnames(Munic2014T1plus1000) <- result
result <- c()
# i <- colnames(Munic2014T2plus1000)[105]
for (i in colnames(Munic2014T2plus1000)) {
i <- str_replace_all(i, "X\\.", "%")
i <- str_replace_all(i, "\\.", " ")
result <- c(result, i)
}
colnames(Munic2014T2plus1000) <- result
rm(i, result)
# On regarde combien de communes fusionnantes sont concernées
nrow(Munic2014T1plus1000)
## [1] 8495
datafus2011 <- subset(df2011, COM_NOUV == "OUI") # Désigne les données concernant les communes ayant participé à la création d'une commune nouvelle, appelées ici communes fusionnantes
Municip2014T1Cfus <- merge(datafus2011[, c("CODGEO", "CODGEO_new", "LIBGEO", "LIBGEO_new", "FusDate")], Munic2014T1plus1000, by = "CODGEO", all.x = TRUE)
table(Munic2014T1plus1000$`Code Nuance1`)
##
## LCOM LDIV LDVD LDVG LEXG LFG LMDM LPG LSOC LUC LUD LUDI LUG LUMP LVEC
## 125 1671 1716 2760 231 277 38 34 674 15 40 178 566 154 16
# Répartition des listes
table(Municip2014T1Cfus$`Code Nuance1`)
##
## LCOM LDIV LDVD LDVG LEXG LFG LMDM LSOC LUC LUD LUDI LUG LUMP LVEC
## 1 139 186 165 3 10 3 33 3 7 12 19 5 1
# Nombre de communes pour lesquelles une nuance politique est renseignée pour la première liste
sum(table(Municip2014T1Cfus$`Code Nuance1`))
## [1] 587
nrow(Municip2014T1Cfus)
## [1] 2671
# Évaluation du nombre de communes fusionnantes ayant une population inférieure à 1000 habitants
summary(datafus2011$P09_POP)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 6 198 404 1012 915 105749
table(datafus2011$P09_POP < 1000)
##
## FALSE TRUE
## 610 2061
100*sum(datafus2011$P09_POP < 1000)/nrow(datafus2011)
## [1] 77.16211
# Recherche de certaines communes, montrant qu'il y a des problèmes
test <- subset (Munic2014T1plus1000, Munic2014T1plus1000$`Code du département` == "36")
test
## [1] Date de l export Code du département Type de scrutin
## [4] Libellé du département Code de la commune Libellé de la commune
## [7] Inscrits Abstentions % Abs Ins
## [10] Votants % Vot Ins Blancs et nuls
## [13] % BlNuls Ins % BlNuls Vot Exprimés
## [16] % Exp Ins % Exp Vot Code Nuance1
## [19] Sexe1 Nom1 Prénom1
## [22] Liste1 Sièges Elu1 Sièges Secteur1
## [25] Sièges CC1 Voix1 % Voix Ins1
## [28] % Voix Exp1 Code Nuance2 Sexe2
## [31] Nom2 Prénom2 Liste2
## [34] Sièges Elu2 Sièges Secteur2 Sièges CC2
## [37] Voix2 % Voix Ins2 % Voix Exp2
## [40] Code Nuance3 Sexe3 Nom3
## [43] Prénom3 Liste3 Sièges Elu3
## [46] Sièges Secteur3 Sièges CC3 Voix3
## [49] % Voix Ins3 % Voix Exp3 Code Nuance4
## [52] Sexe4 Nom4 Prénom4
## [55] Liste4 Sièges Elu4 Sièges Secteur4
## [58] Sièges CC4 Voix4 % Voix Ins4
## [61] % Voix Exp4 Code Nuance5 Sexe5
## [64] Nom5 Prénom5 Liste5
## [67] Sièges Elu5 Sièges Secteur5 Sièges CC5
## [70] Voix5 % Voix Ins5 % Voix Exp5
## [73] Code Nuance6 Sexe6 Nom6
## [76] Prénom6 Liste6 Sièges Elu6
## [79] Sièges Secteur6 Sièges CC6 Voix6
## [82] % Voix Ins6 % Voix Exp6 Code Nuance7
## [85] Sexe7 Nom7 Prénom7
## [88] Liste7 Sièges Elu7 Sièges Secteur7
## [91] Sièges CC7 Voix7 % Voix Ins7
## [94] % Voix Exp7 Code Nuance8 Sexe8
## [97] Nom8 Prénom8 Liste8
## [100] Sièges Elu8 Sièges Secteur8 Sièges CC8
## [103] Voix8 % Voix Ins8 % Voix Exp8
## [106] Code Nuance9 Sexe9 Nom9
## [109] Prénom9 Liste9 Sièges Elu9
## [112] Sièges Secteur9 Sièges CC9 Voix9
## [115] % Voix Ins9 % Voix Exp9 Code Nuance10
## [118] Sexe10 Nom10 Prénom10
## [121] Liste10 Sièges Elu10 Sièges Secteur10
## [124] Sièges CC10 Voix10 % Voix Ins10
## [127] % Voix Exp10 Code Nuance11 Sexe11
## [130] Nom11 Prénom11 Liste11
## [133] Sièges Elu11 Sièges Secteur11 Sièges CC11
## [136] Voix11 % Voix Ins11 % Voix Exp11
## [139] Code Nuance12 Sexe12 Nom12
## [142] Prénom12 Liste12 Sièges Elu12
## [145] Sièges Secteur12 Sièges CC12 Voix12
## [148] % Voix Ins12 % Voix Exp12 colNA1
## [151] colNA2 colNA3 colNA4
## [154] colNA5 colNA6 CODGEO
## <0 lignes> (ou 'row.names' de longueur nulle)
test <- subset (Munic2014T1plus1000, Munic2014T1plus1000$CODGEO == "29274")
test
## Date de l export Code du département Type de scrutin
## 2365 25/03/2014 12:50:58 29 LI2
## Libellé du département Code de la commune Libellé de la commune Inscrits
## 2365 FINISTERE 274 Scaër 00004304
## Abstentions % Abs Ins Votants % Vot Ins Blancs et nuls % BlNuls Ins
## 2365 00001259 29,25 00003045 70,75 00000201 4,67
## % BlNuls Vot Exprimés % Exp Ins % Exp Vot Code Nuance1 Sexe1 Nom1
## 2365 6,60 00002844 66,08 93,40 LSOC M CAVRET
## Prénom1 Liste1 Sièges Elu1 Sièges Secteur1
## 2365 Pierre SCAËR NOUVEAU CAP A GAUCHE 4 0
## Sièges CC1 Voix1 % Voix Ins1 % Voix Exp1 Code Nuance2 Sexe2 Nom2
## 2365 1 00000839 19,49 29,50 LUG F PÉREZ
## Prénom2 Liste2 Sièges Elu2 Sièges Secteur2
## 2365 Paulette POUR SCAËR ENSEMBLE A GAUCHE 3 0
## Sièges CC2 Voix2 % Voix Ins2 % Voix Exp2 Code Nuance3 Sexe3 Nom3
## 2365 0 562 13,06 19,76 LDVD M LE GOFF
## Prénom3 Liste3 Sièges Elu3 Sièges Secteur3 Sièges CC3 Voix3
## 2365 Jean-Yves AGIR POUR SCAËR 22 0 3 1443
## % Voix Ins3 % Voix Exp3 Code Nuance4 Sexe4 Nom4 Prénom4 Liste4
## 2365 33,53 50,74
## Sièges Elu4 Sièges Secteur4 Sièges CC4 Voix4 % Voix Ins4 % Voix Exp4
## 2365 <NA> <NA> <NA> <NA>
## Code Nuance5 Sexe5 Nom5 Prénom5 Liste5 Sièges Elu5 Sièges Secteur5
## 2365 <NA> <NA>
## Sièges CC5 Voix5 % Voix Ins5 % Voix Exp5 Code Nuance6 Sexe6 Nom6 Prénom6
## 2365 <NA> <NA>
## Liste6 Sièges Elu6 Sièges Secteur6 Sièges CC6 Voix6 % Voix Ins6
## 2365 <NA> <NA> <NA> <NA>
## % Voix Exp6 Code Nuance7 Sexe7 Nom7 Prénom7 Liste7 Sièges Elu7
## 2365 <NA>
## Sièges Secteur7 Sièges CC7 Voix7 % Voix Ins7 % Voix Exp7 Code Nuance8
## 2365 <NA> <NA> <NA>
## Sexe8 Nom8 Prénom8 Liste8 Sièges Elu8 Sièges Secteur8 Sièges CC8 Voix8
## 2365 <NA> <NA> <NA> <NA>
## % Voix Ins8 % Voix Exp8 Code Nuance9 Sexe9 Nom9 Prénom9 Liste9
## 2365
## Sièges Elu9 Sièges Secteur9 Sièges CC9 Voix9 % Voix Ins9 % Voix Exp9
## 2365 <NA> <NA> <NA> <NA>
## Code Nuance10 Sexe10 Nom10 Prénom10 Liste10 Sièges Elu10
## 2365 <NA>
## Sièges Secteur10 Sièges CC10 Voix10 % Voix Ins10 % Voix Exp10
## 2365 <NA> <NA> <NA>
## Code Nuance11 Sexe11 Nom11 Prénom11 Liste11 Sièges Elu11
## 2365 <NA>
## Sièges Secteur11 Sièges CC11 Voix11 % Voix Ins11 % Voix Exp11
## 2365 <NA> <NA> <NA>
## Code Nuance12 Sexe12 Nom12 Prénom12 Liste12 Sièges Elu12
## 2365 <NA> <NA> <NA> <NA> <NA> <NA>
## Sièges Secteur12 Sièges CC12 Voix12 % Voix Ins12 % Voix Exp12 colNA1
## 2365 <NA> <NA> <NA> <NA> <NA> <NA>
## colNA2 colNA3 colNA4 colNA5 colNA6 CODGEO
## 2365 <NA> <NA> <NA> <NA> <NA> 29274
À partir du moment où plus de 77 % des communes fusionnantes ont moins de 1000 habitants et n’ont donc pas de nuance politique associée, l’étude de ces résultats ne paraît pas prioritaire
Une étude possible serait de regarder l’homogénéité des communes nouvelles par rapport à la nuance politique.
NB : Les données paraissent partielles au moment de leur import : sur le fichier txt, on a bien les départements 30 à 37 mais sur les données importées on ne les a plus.
# Importation des résultats concernant la nuance politique victorieuse aux élections municipales de 2014
NuanceMunicip2014 <- read.table("data/elections/Municipales2014_NuanceVictorieuse.csv", sep="\t", colClasses = "character", head = TRUE, stringsAsFactors = TRUE)
NuanceMunicip2014$NuanceVictorieuse <- as.factor(NuanceMunicip2014$NuanceVictorieuse) # On met la variable nuance politique en facteur pour permettre la création du tableau
# Si on veut rajouter un niveau "SansNuance" (mais a tendance à brouiller les statistiques)
# levels(NuanceMunicip2014$NuanceVictorieuse) <- c(levels(NuanceMunicip2014$NuanceVictorieuse), "SansNuance")
datafus2011 <- subset(df2011, COM_NOUV == "OUI") # Désigne les données concernant les communes ayant participé à la création d'une commune nouvelle, appelées ici communes fusionnantes
Municip2014NuancesCfus <- merge(datafus2011[, c("CODGEO", "CODGEO_new", "LIBGEO", "LIBGEO_new", "FusDate")], NuanceMunicip2014, by = "CODGEO", all.x = TRUE)
# Si on souhaite, on peut indiquer les communes qui n'ont pas de nuance (évite d'avoir à gérer des NA)
# Municip2014NuancesCfus$NuanceVictorieuse[is.na(Municip2014NuancesCfus$NuanceVictorieuse)] <- "SansNuance"
table(Municip2014NuancesCfus$NuanceVictorieuse)
##
## LCOM LDIV LDVD LDVG LEXD LEXG LFG LFN LMDM LPG LSOC LUC LUD LUDI LUG LUMP
## 1 131 293 77 0 0 0 0 3 0 22 4 17 12 12 15
## LVEC
## 0
# Les communes sans nuances
summary(is.na(Municip2014NuancesCfus$NuanceVictorieuse))
## Mode FALSE TRUE
## logical 587 2084
# Définition d'un tableau comportant le nombre de communes fusionnantes par commune nouvelle
count_CN <- plyr::count(Municip2014NuancesCfus, "CODGEO_new")
mesCommunes <- count_CN$CODGEO_new
# mesCommunes <- c("61324","73150","73006")
#pourinfo <- subset (typo, CODGEO_new == "61324" | CODGEO_new =="73150" | CODGEO_new == "73006")
nclass <- length(levels(Municip2014NuancesCfus$NuanceVictorieuse))
results <- data.frame(matrix(ncol=nclass, nrow=0))
i <- mesCommunes[1]
i <- "61324"
for (i in mesCommunes) { # Pour chaque identifiant de commune nouvelle,
toto <- subset (Municip2014NuancesCfus, CODGEO_new == i ) # Ne garder que les communes fusionnantes y ayant participé
a <- table(toto$NuanceVictorieuse) # Relever les groupes des communes fusionnantes
results <- rbind(results,a) # Combiner les résultats, par lignes
rm(a, toto) # Supprimer "a"
}
# On renomme les colonnes
colnames(results) <- levels(Municip2014NuancesCfus$NuanceVictorieuse)
count_CN <- cbind(count_CN, results)
# count_CN[count_CN == "0"] <- NA
# On identifie la variable la plus fréquente
count_CN$max2 <- apply(count_CN[, 3:(nclass+2)], 1, function(x) max(x, na.rm = TRUE))
# Quel est le groupe de typo revenant le plus fréquemment dans une CN
count_CN$Nuancemaj <- colnames(count_CN[, 3:(nclass+2)])[apply(count_CN[, 3:(nclass+2)], 1, which.max)]
# On supprime la donnée si le maximum est inférieur à 51% du total
count_CN$Nuancemaj <- ifelse(count_CN$freq/2 > count_CN$max2, "PasdeNuanceMajoritaire", count_CN$Nuancemaj)
# On cherche à savoir quelles nuances sont présentes [Ne fonctionne]
# count_CN$Nuances <- colnames(count_CN[, 3:(nclass+2)])[apply(count_CN[, 3:(nclass+2)], 1, is.na)]
count_CN$ComFusavecNuances <- apply(count_CN[, 3:(nclass+2)], 1, sum)
count_CN$ComFussansNuances <- count_CN$freq - count_CN$ComFusavecNuances
summary(count_CN$ComFussansNuances)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.000 1.000 2.000 2.469 3.000 21.000
# Proportions des communes fusionnantes n'ayant pas de nuance, à l'intérieur de chaque commune nouvelle
count_CN$PropComFussansNuances <- round(100*(count_CN$ComFussansNuances / count_CN$freq),2)
summary(count_CN$PropComFussansNuances)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.0 50.0 100.0 76.7 100.0 100.0
print ("Conclusion : Une très forte proportion de communes nouvelles dont au moins une partie des communes fusionnantes n'ont pas de nuance politique officielle suite aux élections municipales de 2014.")
## [1] "Conclusion : Une très forte proportion de communes nouvelles dont au moins une partie des communes fusionnantes n'ont pas de nuance politique officielle suite aux élections municipales de 2014."
# On note si une CN a des communes fusionnantes avec un groupe de typo identique
count_CN$NuanceIdent <- ifelse(count_CN$max == count_CN$freq, TRUE, FALSE)
# summary(count_CN$NuanceIdent)
a <- summary(count_CN$NuanceIdent)
# On note si une CN a des communes fusionnantes avec un groupe de typo presque identique (max 25% de communes ayant un type différent)
count_CN$NuancepresqIdent <- ifelse((count_CN$freq - count_CN$max2)/count_CN$freq <= 0.25, TRUE, FALSE)
# summary(count_CN$NuancepresqIdent)
b <- summary(count_CN$NuancepresqIdent)
tableau <- data.frame(rbind (a, b))
tableau$Mode <- c("Toutes les communes composant une commune nouvelle ont une nuance politique identique", "Au moins 75% des communes composant une commune nouvelle ont une nuance politique identique")
colnames(tableau)<- c("", "Faux", "Vrai")
kable(tableau, align = "c", digits = 0, row.names = FALSE)
| Faux | Vrai | |
|---|---|---|
| Toutes les communes composant une commune nouvelle ont une nuance politique identique | 824 | 20 |
| Au moins 75% des communes composant une commune nouvelle ont une nuance politique identique | 823 | 21 |
CNNuance_connue <- subset(count_CN, count_CN$PropComFussansNuances == "0")
paste0 ("On dispose de ", nrow(CNNuance_connue), " communes dont on connaît la nuance pour toutes les communes fusionnantes.")
## [1] "On dispose de 52 communes dont on connaît la nuance pour toutes les communes fusionnantes."
# Nuance majoritaire pour ces communes :
table(CNNuance_connue$Nuancemaj)
##
## LCOM LDIV LDVD
## 1 14 21
## LDVG LUD LUDI
## 7 5 1
## PasdeNuanceMajoritaire
## 3
# Faible proportion de communes dont on connaît en totalité
table(CNNuance_connue$NuancepresqIdent)
##
## FALSE TRUE
## 32 20
table(CNNuance_connue$NuanceIdent)
##
## FALSE TRUE
## 32 20
kable(table(CNNuance_connue$NuanceIdent))
| Var1 | Freq |
|---|---|
| FALSE | 32 |
| TRUE | 20 |
table(CNNuance_connue$freq)
##
## 2 3 5 6 7
## 43 5 2 1 1
# On extrait les CN ayant des communes fusionnante avec un groupe de typo identique
CNNuanceIdent <- subset(count_CN, NuanceIdent==TRUE)
table(CNNuanceIdent$Nuancemaj)
##
## LDIV LDVD LDVG LUD LUDI
## 4 12 1 2 1
table(CNNuanceIdent$freq)
##
## 2 3 5
## 17 2 1
CNNuanceIdent <- merge(CNNuanceIdent, NuanceMunicip2014[, c("CODGEO", "NuanceVictorieuse")], by.x = "CODGEO_new", by.y = "CODGEO", all.x = TRUE)
# Quel pourcentage de chaque groupe dans les communes nouvelles homogènes ?
tabcont<-summary(CNNuanceIdent$NuanceVictorieuse)
# Quel pourcentage de chaque groupe est majoritaire ?
count_CN$Nuancemaj <- as.factor(count_CN$Nuancemaj)
tabcont2<-summary(count_CN$Nuancemaj)
# Pour comparaison : pourcentages de chaque groupe dans les communes fusionnantes
tabcont3<-summary(NuanceMunicip2014$NuanceVictorieuse)
round(100*prop.table(tabcont,margin=),1) # Pourcentages de chaque groupe en fonction de la totalité des communes nouvelles homogènes
## LCOM LDIV LDVD LDVG LEXD LEXG LFG LFN LMDM LPG LSOC LUC LUD LUDI LUG LUMP
## 0 20 60 5 0 0 0 0 0 0 0 0 10 5 0 0
## LVEC
## 0
round(100*prop.table(tabcont2,margin=),1) # Pourcentages de chaque groupe majoritaire en fonction de la totalité des communes fusionnantes
## LCOM LDIV LDVD
## 0.1 5.3 15.0
## LDVG LMDM LSOC
## 4.1 0.1 0.8
## LUC LUD LUDI
## 0.1 0.8 0.7
## LUG LUMP PasdeNuanceMajoritaire
## 0.2 0.8 71.7
round(100*prop.table(tabcont3,margin=),1) # Pourcentages de chaque groupe en fonction de la totalité des communes fusionnantes
## LCOM LDIV LDVD LDVG LEXD LEXG LFG LFN LMDM LPG LSOC LUC LUD LUDI LUG LUMP
## 0.7 17.6 39.8 20.0 0.0 0.0 0.3 0.1 0.4 0.1 4.9 0.3 4.0 2.8 4.3 4.8
## LVEC
## 0.1
tableau <- rbind(
summary(CNNuanceIdent$NuanceVictorieuse),
round(100*prop.table(tabcont,margin=),1) * 100 / nrow(NuanceMunicip2014),
round(100*prop.table(tabcont,margin=),1),
summary(Municip2014NuancesCfus$NuanceVictorieuse),
round(100*prop.table(tabcont3,margin=),1)
)
row.names(tableau) <- c(
"Nombre de communes nouvelles regroupant des communes homogènes du point de vue de la typologie",
"Pourcentages en fonction de la totalité des communes nouvelles",
"Pourcentages en fonction de la totalité des communes nouvelles homogènes",
"Nombre de communes fusionnantes par groupe",
"Pourcentages de chaque groupe en fonction de la totalité des communes fusionnantes")
kable(tableau, align = "c", digits = 0)
| LCOM | LDIV | LDVD | LDVG | LEXD | LEXG | LFG | LFN | LMDM | LPG | LSOC | LUC | LUD | LUDI | LUG | LUMP | LVEC | NA’s | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Nombre de communes nouvelles regroupant des communes homogènes du point de vue de la typologie | 0 | 4 | 12 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 1 | 0 | 0 | 0 | 0 |
| Pourcentages en fonction de la totalité des communes nouvelles | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Pourcentages en fonction de la totalité des communes nouvelles homogènes | 0 | 20 | 60 | 5 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 10 | 5 | 0 | 0 | 0 | 0 |
| Nombre de communes fusionnantes par groupe | 1 | 131 | 293 | 77 | 0 | 0 | 0 | 0 | 3 | 0 | 22 | 4 | 17 | 12 | 12 | 15 | 0 | 2084 |
| Pourcentages de chaque groupe en fonction de la totalité des communes fusionnantes | 1 | 18 | 40 | 20 | 0 | 0 | 0 | 0 | 0 | 0 | 5 | 0 | 4 | 3 | 4 | 5 | 0 | 1 |
tableau <- rbind(
summary(count_CN$Nuancemaj),
round(100*prop.table(tabcont2,margin=),1)
)
row.names(tableau) <- c(
"Nombre de communes nouvelles ayant un type majoritaire",
"Pourcentages de chaque groupe majoritaire en fonction de la totalité des communes fusionnantes"
)
print ("NB : Les données sont faussées car dans le cas où aucune commune n'a de nuance, le code retourne la première colonne (soit LCOM, ce qui explique sa sur-représentation).")
## [1] "NB : Les données sont faussées car dans le cas où aucune commune n'a de nuance, le code retourne la première colonne (soit LCOM, ce qui explique sa sur-représentation)."
kable(tableau, align = "c", digits = 0)
| LCOM | LDIV | LDVD | LDVG | LMDM | LSOC | LUC | LUD | LUDI | LUG | LUMP | PasdeNuanceMajoritaire | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Nombre de communes nouvelles ayant un type majoritaire | 1 | 45 | 127 | 35 | 1 | 7 | 1 | 7 | 6 | 2 | 7 | 605 |
| Pourcentages de chaque groupe majoritaire en fonction de la totalité des communes fusionnantes | 0 | 5 | 15 | 4 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 72 |
Globalement, les quelques communes qui sont homogènes sont plus fréquemment des communes où ce sont des listes “Divers droite” qui l’ont emporté. Sur-représentation car elles représentent 40% des communes fusionnantes et 61% des communes nouvelles homogènes.
rm(NuanceMunicip2014, Munic2014T1plus1000, Munic2014T2plus1000, Municip2014NuancesCfus, tableau, tabcont, tabcont2, tabcont3, results, mesCommunes, nclass, a, b, i, CNNuanceIdent, count_CN, Municip2014T1Cfus, test)
Les données ont des présentations assez variables mais sont caractérisées par des données en ligne
PR2012_T1_brut <- read_xls("data-raw/elections/2012_presidentielles_T1-T2_communes.xls", sheet = "Tour 1", skip = 0)
PR2012_T2_brut <- read_xls("data-raw/elections/2012_presidentielles_T1-T2_communes.xls", sheet = "Tour 2", skip = 0)
PR2017_T1_brut <- read_xls("data-raw/elections/2017_presidentielles_T1_communes.xls", skip = 3)
PR2017_T2_brut <- read_xls("data-raw/elections/2017_presidentielles_T2_communes.xls", skip = 3)
PR2022_T1_brut <- read_xlsx("data-raw/elections/2022_presidentielles_T1_communes.xlsx", skip = 0)
# Problème dans le nommage des colonnes qui oblige à faire un traitement manuel :
colnames(PR2022_T1_brut)[27:103] <- rep(c("N°Panneau", "Sexe", "Nom", "Prénom", "Voix", "% Voix/Ins", "% Voix/Exp"), times = 11)
PR2022_T2_brut <- read_xlsx("data-raw/elections/2022_presidentielles_T2_communes.xlsx", skip = 0)
# Eur_2014_brut <- read_xlsx("data-raw/elections/2014_europeennes_communes.xlsx", skip = 0)
# Eur_2019_brut <- read_xls("data-raw/elections/2019_europeennes_communes.xls", skip = 0)
# str(PR2012_T1)
noms_scrutins_presid <- c("PR2012_T1", "PR2012_T2", "PR2017_T1", "PR2017_T2", "PR2022_T1", "PR2022_T2")
# noms_scrutins_presid <- c("PR2022_T1", "PR2022_T2")
nom_scrutin <- noms_scrutins_presid[1]
# Pour comparer les noms de colonnes des scrutins
for (nom_scrutin in noms_scrutins_presid) {
scrutin <- get(paste0(nom_scrutin, "_brut"))
print(colnames(scrutin))
}
# Conclusion : les colonnes ne sont pas identiques, même pour les premières variables
for (nom_scrutin in noms_scrutins_presid) {
scrutin <- get(paste0(nom_scrutin, "_brut"))
# scrutin <- scrutin[1:10,] # Pour tests
# On recherche les colonnes qui comportent les noms des candidats
num_col_candidats <- c(grep(pattern = "Nom", colnames(scrutin), ignore.case = FALSE))
# On recherhe maintenant le nom des candidats
# [À AMÉLIORER] Utilisation d'une boucle parce que je ne vois pas de fonction adaptée pour ce que je veux faire
noms_candidats <- vector()
for (i in num_col_candidats) {
noms_candidats_i <- unique(scrutin[i])
noms_candidats <- c(noms_candidats, noms_candidats_i)
}
rm(noms_candidats_i, i)
noms_candidats <- unlist(noms_candidats)
noms_candidats <- unique(noms_candidats)
# Boucle car, pour quelques listes, il est nécessaire de rajouter des zéros, car codes incomplets
for (ligne in 1:nrow(scrutin)) {
scrutin[ligne, "Code_Com"] <- paste0(paste0(rep(0, 3-nchar(scrutin[ligne, "Code de la commune"])), collapse = ""), scrutin[ligne, "Code de la commune"])
scrutin[ligne, "Code_Dep"] <- paste0(paste0(rep(0, 2-nchar(scrutin[ligne, "Code du département"])), collapse = ""), scrutin[ligne, "Code du département"])
} # Fin boucle par ligne pour rendre propre les codes communes et département
# On archive le nombre de colonne pour savoir quelle partie du tableau ne pas garder
dim_tabl <- ncol(scrutin)
# Sélection des variables qui nous intéressent
scrutin$CODGEO <- paste0(scrutin$Code_Dep, scrutin$Code_Com)
# On reprend les autres variables qui nous intéressent
scrutin$Inscr_nbre <- as.numeric(scrutin$Inscrits) # as.numeric car un problème avec scrutin PR2022_T1
scrutin$Abst_nbre <- scrutin$Abstentions
scrutin$Votants_nbre <- scrutin$Votants
scrutin$Expr_nbre <- scrutin$Exprimés
# Calculs de quelques variables, les pourcentages sont calculés à partir du nombre d'inscrits ou du nombre de votants (pour les blancs, nuls, les candidats etc)
scrutin$Abst_prct_insc <- round(100 * scrutin$Abst_nbre / scrutin$Inscr_nbre, 2)
scrutin$Expr_prct_insc <- round(100 * scrutin$Expr_nbre / scrutin$Inscr_nbre, 2)
scrutin$Votants_prct_insc <- round(100 * scrutin$Votants_nbre / scrutin$Inscr_nbre, 2)
# Blancs et nuls pas distingués avant 2014 donc champs rempli pour permettre la suite du traitement
if ( sjmisc::is_empty(grep(pattern = "Blancs et nuls", colnames(scrutin), ignore.case = FALSE)) == FALSE ) {# Si une colonne porte le nom "Blancs et nuls" (meilleure formulation de la condition à trouver)
scrutin$BlcsNuls_nbre <- scrutin$`Blancs et nuls`
scrutin$BlcsNuls_prct_insc <- round(100 * scrutin$BlcsNuls_nbre / scrutin$Inscr_nbre, 2)
scrutin$BlcsNuls_prct_vote <- round(100 * scrutin$BlcsNuls_nbre / scrutin$Votants_nbre, 2)
} else { # Traitement blancs et nuls séparés
scrutin$Blancs_nbre <- scrutin$Blancs
scrutin$Nuls_nbre <- scrutin$Nuls
scrutin$Blancs_prct_insc <- round(100 * scrutin$Blancs_nbre / scrutin$Inscr_nbre, 2)
scrutin$Nuls_prct_insc <- round(100 * scrutin$Nuls_nbre / scrutin$Inscr_nbre, 2)
scrutin$Blancs_prct_vote <- round(100 * scrutin$Blancs_nbre / scrutin$Votants_nbre, 2)
scrutin$Nuls_prct_vote <- round(100 * scrutin$Nuls_nbre / scrutin$Votants_nbre, 2)
} # Fin du "else" (traitement blancs et nuls séparés)
# candidat <- noms_candidats[1] # Pour tests
for (candidat in noms_candidats) {
# Pour chaque candidat, on veut son nombre de voix
# Traitement par boucle nécessaire surtout pour élections 2017 car les candidats n'ont pas toujours le même numéro de colonne
## Tentative (échec) de fonctionner avec which
# On recherche le numéro de la colonne pour laquelle la valeur est le nom du candidat
# which(scrutin == candidat, arr.ind = TRUE)[, 2]
# On lui ajoute 2 (pour avoir le nombre de voix)
# Et cela donne le score en valeur absolue du candidat en question
# Nécessité de passer par un tableau à part car la fonction wich recherche colonne par colonne et non ligne par ligne donc ordre perturbé
# temp <- as.data.frame(which(scrutin == candidat, arr.ind = TRUE))
# temp <- temp[order(temp$row),]
# scrutin$temp <- temp$col
# On extrait la valeur de la colonne décalée de 2 pour le nom du candidat, pour avoir le nombre de voix
# scrutin[, paste0("nb_voix_", candidat)] <- scrutin[scrutin$temp+2][1]
# Problème si ce n'est pas la même colonne
## Fonctionnement par boucle
for (ligne in 1:nrow(scrutin)) {
scrutin[ligne, paste0("nbre_voix_", candidat)] <- scrutin[ligne, which(scrutin[ligne,] == candidat, arr.ind = TRUE)[, 2]+2]
} # Fin boucle par ligne pour nombre voix
scrutin[, paste0("prct_expr_", candidat)] <- round(100 * scrutin[, paste0("nbre_voix_", candidat)] / scrutin$Expr_nbre, 2)
scrutin[, paste0("prct_insc_", candidat)] <- round(100 * scrutin[, paste0("nbre_voix_", candidat)] / scrutin$Inscr_nbre, 2)
} # Fin boucle par candidat
scrutin <- scrutin[, c(dim_tabl:ncol(scrutin))]
# Export pour sauvegarde
write.table(scrutin, paste0("data/elections/", nom_scrutin, ".csv"), sep="\t", dec = ",", row.names=FALSE)
assign(nom_scrutin, scrutin)
}
PR2017_T1_BVot_brut <- read.table("data-raw/elections/2017_presidentielles_T1_bureaux_de_vote.txt", head = FALSE, sep = ";", stringsAsFactors = FALSE, fileEncoding = "latin1", fill = TRUE, quote="\"")
colnames(PR2017_T1_BVot_brut) <- PR2017_T1_BVot_brut[1,] # On récupère le nom des colonnes qui sont dans la première ligne, ligne qu'on supprime juste après
PR2017_T1_BVot_brut <- PR2017_T1_BVot_brut[-1,]
print(colnames(PR2017_T1_BVot_brut))
colnames(PR2017_T1_BVot_brut) <- c(colnames(PR2017_T1_BVot_brut)[1:28], rep(colnames(PR2017_T1_BVot_brut)[22:28],10)) # On rajoute les identifiants de colonnes qui manquent
colnames(PR2017_T1_BVot_brut)
PR2017_T2_BVot_brut <- read.table("data-raw/elections/2017_presidentielles_T2_bureaux_de_vote.txt", head = FALSE, sep = ";", stringsAsFactors = FALSE, fileEncoding = "latin1", fill = TRUE, quote="\"")
colnames(PR2017_T2_BVot_brut) <- PR2017_T2_BVot_brut[1,] # On récupère le nom des colonnes qui sont dans la première ligne, ligne qu'on supprime juste après
PR2017_T2_BVot_brut <- PR2017_T2_BVot_brut[-1,]
print(colnames(PR2017_T2_BVot_brut))
colnames(PR2017_T2_BVot_brut) <- c(colnames(PR2017_T2_BVot_brut)[1:28], rep(colnames(PR2017_T2_BVot_brut)[22:28],1)) # On rajoute les identifiants de colonnes qui manquent
colnames(PR2017_T2_BVot_brut)
PR2022_T1_BVot_brut <- read.table("data-raw/elections/2022_presidentielles_T1_bureaux_de_vote.txt", head = FALSE, sep = ";", stringsAsFactors = FALSE, fileEncoding = "latin1", fill = TRUE, quote="\"")
colnames(PR2022_T1_BVot_brut) <- PR2022_T1_BVot_brut[1,] # On récupère le nom des colonnes qui sont dans la première ligne, ligne qu'on supprime juste après
PR2022_T1_BVot_brut <- PR2022_T1_BVot_brut[-1,]
print(colnames(PR2022_T1_BVot_brut))
colnames(PR2022_T1_BVot_brut) <- c(colnames(PR2022_T1_BVot_brut)[1:28], rep(colnames(PR2022_T1_BVot_brut)[22:28],11))# On rajoute les identifiants de colonnes qui manquent
colnames(PR2022_T1_BVot_brut)
# PR2017_T2_BVot <- PR2022_T1_BVot # Pour retester avec d'autres données sans modifier le texte
Section qui permet de mettre en forme l’ensemble des données des bureaux de vote. Peu utilisée puisque nécessité de traiter les communes fusionnantes de manière assez spécifique dont mise en forme faite en même temps que la jonction entre les tables (plus bas).
noms_scrutins_presid_BV <- c("PR2017_T1_BVot", "PR2017_T2_BVot", "PR2022_T1_BVot")
# noms_scrutins_presid <- c("PR2022_T1", "PR2022_T2")
nom_scrutin <- noms_scrutins_presid_BV[1]
for (nom_scrutin in noms_scrutins_presid_BV) {
scrutin <- get(paste0(nom_scrutin, "_brut"))
# scrutin <- scrutin[1:10,] # Pour tests
# On recherche les colonnes qui comportent les noms des candidats
num_col_candidats <- c(grep(pattern = "Nom", colnames(scrutin), ignore.case = FALSE))
# On recherhe maintenant le nom des candidats
# [À AMÉLIORER] Utilisation d'une boucle parce que je ne vois pas de fonction adaptée pour ce que je veux faire
noms_candidats <- vector()
for (i in num_col_candidats) {
noms_candidats_i <- unique(scrutin[i])
noms_candidats <- c(noms_candidats, noms_candidats_i)
}
rm(noms_candidats_i, i)
noms_candidats <- unlist(noms_candidats)
noms_candidats <- unique(noms_candidats)
# On recrée une variable CODGEO
scrutin$Code_Com <- scrutin$`Code de la commune`
scrutin$Code_Dep <- scrutin$`Code du département`
colnames(scrutin)
summary(nchar(scrutin$Code_Com)) # Si pas égale à 3, dé-commenter la boucle suivante
# Boucle car, pour quelques listes, il est nécessaire de rajouter des zéros, car codes incomplets
# for (ligne in 1:nrow(scrutin)) {
# scrutin[ligne, "Code_Com"] <- paste0(paste0(rep(0, 3-nchar(scrutin[ligne, "Code de la commune"])), collapse = ""), scrutin[ligne, "Code de la commune"])
#
# scrutin[ligne, "Code_Dep"] <- paste0(paste0(rep(0, 2-nchar(scrutin[ligne, "Code du département"])), collapse = ""), scrutin[ligne, "Code du département"])
#
# } # Fin boucle par ligne pour rendre propre les codes communes et département
# Création d'une variable CODGEO
scrutin$CODGEO <- paste0(scrutin$Code_Dep, scrutin$Code_Com)
# On archive le nombre de colonne pour ensuite pouvoir ne conserver que les colonnes justement à partir de ce CODGEO
dim_tabl <- ncol(scrutin)
# Il faut identifier chaque bureau de vote. On va utiliser le format des géométries qui seront importées plus loin, qui paraît être le CODGEO complété par le numéro de bureau
# On passe la variable indiquant le code du bureau de vote au format numérique (pour enlever les premiers zéros)
# scrutin$`Code du b.vote` <- as.numeric(scrutin$`Code du b.vote`)
# Autre solution, qui permet de garder quelques bureaux avec des lettres, enlever les zéros quand ils sont à gauche
scrutin$`Code du b.vote` <- gsub("^0+", "", scrutin$`Code du b.vote`)
table(scrutin$`Code du b.vote`)
# Et, enfin, on concatène les deux
scrutin$code_bureau <- paste0(scrutin$CODGEO, "_", scrutin$`Code du b.vote`)
# NB : Seuls les bureaux de vote de Caen comportent des données intégrant un point et étant donc perçues comme avec des décimales, mais pas trop problématiques ensuite car pas concernés par les communes nouvelles.
# On reprend les autres variables qui nous intéressent en les indiquant comme variables numériques
scrutin$Inscr_nbre <- as.numeric(scrutin$Inscrits)
scrutin$Abst_nbre <- as.numeric(scrutin$Abstentions)
scrutin$Votants_nbre <- as.numeric(scrutin$Votants)
scrutin$Expr_nbre <- as.numeric(scrutin$Exprimés)
# Calculs de quelques variables, les pourcentages sont calculés à partir du nombre d'inscrits ou du nombre de votants (pour les blancs, nuls, les candidats etc)
scrutin$Abst_prct_insc <- round(100 * scrutin$Abst_nbre / scrutin$Inscr_nbre, 2)
scrutin$Expr_prct_insc <- round(100 * scrutin$Expr_nbre / scrutin$Inscr_nbre, 2)
scrutin$Votants_prct_insc <- round(100 * scrutin$Votants_nbre / scrutin$Inscr_nbre, 2)
# Blancs et nuls pas distingués avant 2014 donc champ rempli pour permettre la suite du traitement
if ( sjmisc::is_empty(grep(pattern = "Blancs et nuls", colnames(scrutin), ignore.case = FALSE)) == FALSE ) {# Si une colonne porte le nom "Blancs et nuls" (meilleure formulation de la condition à trouver)
scrutin$BlcsNuls_nbre <- as.numeric(scrutin$`Blancs et nuls`)
scrutin$BlcsNuls_prct_insc <- round(100 * scrutin$BlcsNuls_nbre / scrutin$Inscr_nbre, 2)
scrutin$BlcsNuls_prct_vote <- round(100 * scrutin$BlcsNuls_nbre / scrutin$Votants_nbre, 2)
} else { # Traitement blancs et nuls séparés
scrutin$Blancs_nbre <- as.numeric(scrutin$Blancs)
scrutin$Nuls_nbre <- as.numeric(scrutin$Nuls)
scrutin$Blancs_prct_insc <- round(100 * scrutin$Blancs_nbre / scrutin$Inscr_nbre, 2)
scrutin$Nuls_prct_insc <- round(100 * scrutin$Nuls_nbre / scrutin$Inscr_nbre, 2)
scrutin$Blancs_prct_vote <- round(100 * scrutin$Blancs_nbre / scrutin$Votants_nbre, 2)
scrutin$Nuls_prct_vote <- round(100 * scrutin$Nuls_nbre / scrutin$Votants_nbre, 2)
} # Fin du "else" (traitement blancs et nuls séparés)
# candidat <- noms_candidats[1] # Pour tests
for (candidat in noms_candidats) {
# Pour chaque candidat, on veut son nombre de voix
# Traitement par boucle nécessaire surtout pour élections 2017 car les candidats n'ont pas toujours le même numéro de colonne
## Tentative (échec) de fonctionner avec which
# On recherche le numéro de la colonne pour laquelle la valeur est le nom du candidat
# which(scrutin == candidat, arr.ind = TRUE)[, 2]
# On lui ajoute 2 (pour avoir le nombre de voix)
# Et cela donne le score en valeur absolue du candidat en question
# Nécessité de passer par un tableau à part car la fonction wich recherche colonne par colonne et non ligne par ligne donc ordre perturbé
# temp <- as.data.frame(which(scrutin == candidat, arr.ind = TRUE))
# temp <- temp[order(temp$row),]
# scrutin$temp <- temp$col
# On extrait la valeur de la colonne décalée de 2 pour le nom du candidat, pour avoir le nombre de voix
# scrutin[, paste0("nb_voix_", candidat)] <- scrutin[scrutin$temp+2][1]
# Problème si ce n'est pas la même colonne
## Fonctionnement par boucle
for (ligne in 1:nrow(scrutin)) {
scrutin[ligne, paste0("nbre_voix_", candidat)] <- as.numeric(scrutin[ligne, which(scrutin[ligne,] == candidat, arr.ind = TRUE)[, 2]+2])
} # Fin boucle par ligne pour nombre voix
scrutin[, paste0("prct_expr_", candidat)] <- round(100 * scrutin[, paste0("nbre_voix_", candidat)] / scrutin$Expr_nbre, 2)
scrutin[, paste0("prct_insc_", candidat)] <- round(100 * scrutin[, paste0("nbre_voix_", candidat)] / scrutin$Inscr_nbre, 2)
} # Fin boucle par candidat
scrutin <- scrutin[, c(dim_tabl:ncol(scrutin))]
# Export pour sauvegarde
write.table(scrutin, paste0("data/elections/", nom_scrutin, ".csv"), sep="\t", dec = ",", row.names=FALSE)
assign(nom_scrutin, scrutin)
}
# Pour vérifier quelques données manuellement
test_brut <- subset(PR2017_T1_BVot_brut, PR2017_T1_BVot_brut$`Libellé de la commune` == "Orléans")
test <- subset(PR2017_T1_BVot, PR2017_T1_BVot$CODGEO == "45234")
Une méthode est désormais proposée par l’INSEE, à partir de l’adresse des électeurs, pour déterminer les géométries des bureaux de vote.
Cf. https://inseefrlab.github.io/mapvotr/index.html et https://blog.insee.fr/a-vote-a-chaque-bureau-de-vote-ses-electeurs/
Frédéric Rodrigoa mis en œuvre cette méthode et propose une géométrie des bureaux de vote ici : https://www.data.gouv.fr/fr/datasets/reconstruction-automatique-de-la-geometrie-des-bureaux-de-vote-depuis-insee-reu-et-openstreetmap/. Il détaille la méthode mise en œuvre (et ses limites) ici https://makina-corpus.com/sig-cartographie/une-approche-de-reconstruction-automatique-de-la-geometrie-des-bureaux-de-vote
# download.file("https://www.data.gouv.fr/fr/datasets/r/d2392385-c12f-4b1b-8940-37da09be6333", "data-raw/elections/bureau-de-vote-insee-reu-openstreetmap.gpkg")
bureaux <- st_read("data-raw/elections/bureau-de-vote-insee-reu-openstreetmap.gpkg",
# layer = "geomfus2011",
quiet = TRUE)
# Création d'un champs Département
bureaux$CODE_DEPT <- substr(bureaux$insee, start =1, stop = 2)
table(bureaux$CODE_DEPT)
# Suppression de la Corse et des départements ultra-marins
bureaux <- subset(bureaux, bureaux$CODE_DEPT != "2A" &
bureaux$CODE_DEPT != "2B" &
bureaux$CODE_DEPT != "97")
# Connaître le type de projection
st_crs(bureaux)
st_crs(geom2011)
# On transforme la projection des bureaux de vote dans la projection de la géométrie utilisée
bureaux <- st_transform(bureaux, crs = 3035)
# ====
# Nécessité de formaliser un peu les données du dataframe "bureaux"
# On identifie les intitulés des colonnes en partant de l'exemple des élections 2017
colnames(bureaux)
# Explortion des champs identifiants les bureaux de vote
table(bureaux$bureau)
# table(PR2017_T1_BVot$code_bureau) # Les modifications effectuées sur cette donnée (concaténation du CODGEO et du numéro du bureau de vote) permettent visiblement d'espérer joindre les deux tables, sera fait plus tard
summary(is.na(bureaux$bureau)) # Nécessite de compléter des lignes absentes
# summary(is.na(PR2017_T1_BVot_brut$`Code du b.vote`)) # Entièrement rempli, mais sera mis en forme plus tard
# bureaux_sauvegarde <- bureaux
# On crée un autre champ pour identifier tous les bureaux (certains ne sont pas renseignés)
bureaux$bureau2 <- ifelse(is.na(bureaux$bureau), paste0(bureaux$insee, "_1"), bureaux$bureau)
# Vérification que la structure est correcte
bureaux$bureau2
summary(is.na(bureaux$bureau2))
# On cherche le centroide de chaque bureau
# bureaux_centroides <- st_centroid(bureaux)
# Obtient de meilleurs résultats
bureaux_centroides <- st_point_on_surface(bureaux)
# st_write(obj = bureaux, dsn = "data/elections/bureaux.gpkg", layer = "bureaux", delete_layer = TRUE, quiet = TRUE)
bureaux <- st_read("data/elections/bureaux.gpkg", layer = "bureaux", quiet = TRUE)
Aucun champ précis ne permet immédiatement de joindre la table des résultats des élections en fonction des bureaux de vote et la géométrie proposée par Frédéric Rodrigo. La question qui est posée est donc de savoir si cela est techniquement possible et, tout simplement, si les bureaux correspondent (ce qui n’est pas certain, on ne dispose pas de dates pour la validité de ces bureaux).
Notre objectif n’est pas réellement d’avoir une vision à l’échelle des bureaux de vote mais plutôt d’observer les résultats à l’échelle des communes fusionnantes. Étape transitoire pour arriver aux données par bureaux de vote pour les communes fusionnantes.
# ====
# Quel bureau de vote correspond à quelles communes fusionnantes ?
# Création d'un tableau avec, uniquement pour les communes fusionnantes, quelques identifiants et les géométries
datafus2011_jonction <- merge(geomfus2011, df2011[, c("CODGEO", "LIBGEO", "CODGEO_new", "LIBGEO_new", "FusDate")], by = "CODGEO", all.x = TRUE)
class(datafus2011_jonction)
datafus2011_jonction <- st_join(x = datafus2011_jonction, y = bureaux_centroides, join = st_intersects)
summary(is.na(datafus2011_jonction$insee))
summary(is.na(datafus2011_jonction$LIBGEO))
# summary(duplicated(datafus2011_jonction$bureau2))
# tab_doublons <- datafus2011_jonction[duplicated(datafus2011_jonction$bureau2) | duplicated(datafus2011_jonction$bureau2, fromLast = TRUE), ]
# plot(tab_doublons$geometry)
summary(is.na(datafus2011_jonction$bureau2))
tab_NA <- datafus2011_jonction[is.na(datafus2011_jonction$bureau2),]
plot(tab_NA$geometry)
table(duplicated(datafus2011_jonction$LIBGEO))
tab_doublons <- datafus2011_jonction[duplicated(datafus2011_jonction$LIBGEO) | duplicated(datafus2011_jonction$LIBGEO, fromLast = TRUE), ]
length(unique(tab_doublons$CODGEO))
La jointure est globalement plutôt efficace, mais il y a quand même une perte de 418 entités pour lesquelles il n’est pas possible d’associer un bureau de vote.
L’autre problème qui se pose est que une partie des communes fusionnantes (416 exactement) sont composées de plusieurs bureaux de vote. Il va donc falloir prévoir de regrouper ces données.
Ancienne jointure (désormais cette jointure est intégrée à la mise en forme des données). Nécessite les données sur les bureaux de vote, déjà formalisées.
Peut servir pour joindre les données Il s’agit maintenant de joindre aux données de la base DAC les données des élections par bureau de vote, grâce aux identifiants des bureaux de vote, récupérés grâce aux géométries de ces derniers.
# Va être à faire pour chaque scrutin
noms_scrutins_presid_BV <- c("PR2017_T1_BVot", "PR2017_T2_BVot", "PR2022_T1_BVot")
nom_scrutin <- noms_scrutins_presid_BV[1]
# Import données
for (nom_scrutin in noms_scrutins_presid_BV) {
# Import des données
scrutin <- read.table(paste0("data/elections/", nom_scrutin, ".csv"),
sep="\t", colClasses = "character", head = TRUE, stringsAsFactors = TRUE)
# On refait l'import maintenant qu'on connaît la longueur du tableau, en spécifiant le type de données
scrutin <- read.table(paste0("data/elections/", nom_scrutin, ".csv"),
sep="\t",
colClasses = c(rep("character", 2), rep("numeric", length(scrutin) -2)),
head = TRUE, stringsAsFactors = TRUE, dec =",")
# On se focalise uniquement sur les communes fusionnantes qui nous intéressent
# On retire les fusions postérieures à la date du scrution car leurs données sont nécessairement disponibles dans les résultats par communes, a priori plus fiables car pas de jonction un peu aléatoire
# Nécessite de définir l'année
annee <- substr(nom_scrutin, start = 3, stop = 6)
datafus2011_jonction_scrutin <- subset(datafus2011_jonction, datafus2011_jonction$FusDate < paste0(annee, "-05-01"))
scrutin <- merge (scrutin, datafus2011_jonction_scrutin, by.x = "code_bureau", by.y = "bureau2", all.x = FALSE, all.y = TRUE)
summary(scrutin$geom) # Vérifier qu'ils ont tous une géométrie
summary(is.na(scrutin$code_bureau)) # Pour voir les communes fusionnantes qui n'ont pas de bureaux référencés
# On s'assure que le CODGEO à conserver (celui de la base DAC, pas celui concaténé à partir des données des bureaux) reste bien lisible
scrutin <- rename.variable(scrutin, "CODGEO.y", "CODGEO")
colnames(scrutin)
}
Bilan : Il est globalement possible de faire une jonction entre les résultats de l’élection présidentielle 2017 et les géométries des bureaux de vote, mais cela signifie une perte d’environ 10% des bureaux de vote concernés. Cela paraît raisonnable, surtout si on ne perd alors qu’une partie des communes fusionnantes (et que pour les autres on reste sur les données communales).
La perte est bien plus limitée (69 bureaux sur presque 3000 de bons) pour l’élection 2022.
noms_scrutins_presid_BV <- c("PR2017_T1_BVot", "PR2017_T2_BVot", "PR2022_T1_BVot")
# noms_scrutins_presid <- c("PR2022_T1", "PR2022_T2")
nom_scrutin <- noms_scrutins_presid_BV[1]
datafus2011_jonction$FusDate <- as.Date(datafus2011_jonction$FusDate, tryFormats = "%Y-%m-%d")
class(datafus2011_jonction$FusDate)
# Besoin d'une fonction pour gérer les doublons
# Permet de désigner toutes les lignes qui sont concernées par des doublons
duplicated2 <- function(x){
if (sum(dup <- duplicated(x))==0)
return(dup)
if (class(x) %in% c("data.frame","matrix"))
duplicated(rbind(x[dup,],x))[-(1:sum(dup))]
else duplicated(c(x[dup],x))[-(1:sum(dup))]
}
# Import données
for (nom_scrutin in noms_scrutins_presid_BV) {
scrutin <- get(paste0(nom_scrutin, "_brut"))
# scrutin <- scrutin[1:10,] # Pour tests
# On recrée une variable CODGEO
scrutin$Code_Com <- scrutin$`Code de la commune`
scrutin$Code_Dep <- scrutin$`Code du département`
colnames(scrutin)
summary(nchar(scrutin$Code_Com)) # Si pas égale à 3, dé-commenter la boucle suivante
# Boucle car, pour quelques listes, il est nécessaire de rajouter des zéros, car codes incomplets
# for (ligne in 1:nrow(scrutin)) {
# scrutin[ligne, "Code_Com"] <- paste0(paste0(rep(0, 3-nchar(scrutin[ligne, "Code de la commune"])), collapse = ""), scrutin[ligne, "Code de la commune"])
#
# scrutin[ligne, "Code_Dep"] <- paste0(paste0(rep(0, 2-nchar(scrutin[ligne, "Code du département"])), collapse = ""), scrutin[ligne, "Code du département"])
#
# } # Fin boucle par ligne pour rendre propre les codes communes et département
# Création d'une variable CODGEO
scrutin$CODGEO <- paste0(scrutin$Code_Dep, scrutin$Code_Com)
# On archive le nombre de colonne pour ensuite pouvoir ne conserver que les colonnes justement à partir de ce CODGEO
dim_tabl <- ncol(scrutin)
# Il faut identifier chaque bureau de vote. On va utiliser le format des géométries qui seront importées plus loin, qui paraît être le CODGEO complété par le numéro de bureau
# On passe la variable indiquant le code du bureau de vote au format numérique (pour enlever les premiers zéros)
# scrutin$`Code du b.vote` <- as.numeric(scrutin$`Code du b.vote`)
# Autre solution, qui permet de garder quelques bureaux avec des lettres, enlever les zéros quand ils sont à gauche
scrutin$`Code du b.vote` <- gsub("^0+", "", scrutin$`Code du b.vote`)
table(scrutin$`Code du b.vote`)
# Et, enfin, on concatène les deux
scrutin$code_bureau <- paste0(scrutin$CODGEO, "_", scrutin$`Code du b.vote`)
# NB : Seuls les bureaux de vote de Caen comportent des données intégrant un point et étant donc perçues comme avec des décimales, mais pas trop problématiques ensuite car pas concernés par les communes nouvelles.
# À PARTIR D'ICI, COMMENCE LA JOINTURE AVEC LES DONNÉES DES COMMUNES FUSIONNANTES
# On se focalise uniquement sur les communes fusionnantes qui nous intéressent
# On retire les fusions postérieures à la date du scrution car leurs données sont nécessairement disponibles dans les résultats par communes, a priori plus fiables car pas de jonction un peu aléatoire
# Nécessite de définir l'année
annee <- substr(nom_scrutin, start = 3, stop = 6)
# On ne sélectionne que les communes ayant fusionné avant la date des élections
datafus2011_jonction_scrutin <- subset(datafus2011_jonction, datafus2011_jonction$FusDate < paste0(annee, "-05-01"))
datafus2011_jonction_scrutin$FusDate <- as.character(datafus2011_jonction_scrutin$FusDate) # Pour ne pas bloquer la fonction which plus bas
datafus2011_jonction_scrutin <- subset(datafus2011_jonction_scrutin, !is.na(datafus2011_jonction_scrutin$bureau2))
scrutin <- merge (scrutin, datafus2011_jonction_scrutin, by.x = "code_bureau", by.y = "bureau2", all.x = FALSE, all.y = TRUE)
summary(scrutin$geom) # Vérifier qu'ils ont tous une géométrie
scrutin <- subset(scrutin, select = -geometry) # Géométrie qu'on retire pour simplifier les traitements ensuite
summary(is.na(scrutin$code_bureau)) # Pour voir les communes fusionnantes qui n'ont pas de bureaux référencés
summary(is.na(scrutin$`Code du b.vote`)) # Pour voir les communes fusionnantes qui n'ont pas de bureaux référencés dans les résultats (donc pas de résultats)
scrutin <- subset(scrutin, !is.na( scrutin$`Code du b.vote`))# On enlève ces données
# On s'assure que le CODGEO à conserver (celui de la base DAC, pas celui concaténé à partir des données des bureaux) reste bien lisible
scrutin <- rename.variable(scrutin, "CODGEO.y", "CODGEO")
colnames(scrutin)
# Or, pour certaines communes fusionnantes, il y a plusieurs bureaux de vote. Comme ce n'est pas l'échelle qui nous intéresse, il faut repérer ces communes et additionner les champs de valeurs absolues (ceux qui seront utilisés ensuite)
table(duplicated(scrutin$CODGEO))
tab_doublons <- scrutin[duplicated(scrutin$CODGEO) | duplicated(scrutin$CODGEO, fromLast = TRUE), ]
print(paste0("Pour le scrutin ", nom_scrutin, ", le nombre de communes fusionnantes ayant plusieurs bureaux de vote est de ", length(unique(tab_doublons$CODGEO))))
# Du coup, on va distinguer le traitement pour les communes fusionnantes qui ont plusieurs bureaux de vote (on les considère comme des doublons) et les autres
# On indique cela dans un champs
scrutin$plusieurs_BV <- duplicated2(scrutin$CODGEO)
summary(scrutin$plusieurs_BV)
scrutin_doublons <- subset(scrutin, scrutin$plusieurs_BV == TRUE)
scrutin_sans_doublons <- subset(scrutin, scrutin$plusieurs_BV == FALSE)
# colnames(scrutin_sans_doublons)
# On prépare un tableau pour accueillir les données des variables agrégées
doublons_agreges <- scrutin_doublons %>% group_by(CODGEO) %>% filter (! duplicated(CODGEO))
sommes_agreges <- data.frame(unique(scrutin_doublons$CODGEO)) # Un tableau vide pour accueillir les sommes
colnames(sommes_agreges) <- "CODGEO"
# On recherche les colonnes qui comportent les noms des candidats
num_col_candidats <- c(grep(pattern = "Nom", colnames(scrutin), ignore.case = FALSE))
# On recherhe maintenant le nom des candidats
# [À AMÉLIORER] Utilisation d'une boucle parce que je ne vois pas de fonction adaptée pour ce que je veux faire
noms_candidats <- vector()
for (i in num_col_candidats) {
noms_candidats_i <- unique(scrutin[i])
noms_candidats <- c(noms_candidats, noms_candidats_i)
}
rm(noms_candidats_i, i)
noms_candidats <- unlist(noms_candidats)
noms_candidats <- unique(noms_candidats)
colnames(scrutin_doublons)
# Repérer les colonnes dont j'ai besoin
colonnes_a_agreger <- c("Inscrits", "Abstentions", "Votants", "Blancs", "Nuls", "Exprimés", colnames(scrutin_doublons[,num_col_candidats +2]))
# On les passe en numériques
scrutin_doublons[colonnes_a_agreger]<- lapply(scrutin_doublons[colonnes_a_agreger], as.numeric)
# sapply(scrutin_doublons, class)
# variable <- colonnes_a_agreger[1]
for (variable in colonnes_a_agreger) { # Pour chaque colonne qui nous intéresse
# Faire la somme, la stocker dans sommes_agreges
# Démarche un peu lourdingue mais permet de se prémunir contre les éventuels décalages
sommes <- as.data.frame(tapply(scrutin_doublons [, variable] , scrutin_doublons$CODGEO, sum, na.rm = TRUE))
colnames(sommes) <- variable
sommes$CODGEO <- row.names(sommes)
sommes_agreges <- merge (sommes_agreges, sommes, by = "CODGEO")
}
rm(variable, sommes)
# On supprime dans doublons_agreges les colonnes qu'on va remplacer
doublons_agreges <- doublons_agreges[ , ! colnames(doublons_agreges) %in% colonnes_a_agreger]
# Faire la jonction avec doublons_agreges
doublons_agreges <- merge (doublons_agreges, sommes_agreges, by = "CODGEO")
# On adapte les classes de données
scrutin_sans_doublons[colonnes_a_agreger]<- lapply(scrutin_sans_doublons[colonnes_a_agreger], as.numeric)
# puis on regoupe avec scrutin_sans_doublons
scrutin <- bind_rows (scrutin_sans_doublons, doublons_agreges)
summary(is.na(scrutin$`Libellé du département`))
# Reprise de la mise en forme des données
# On reprend les autres variables qui nous intéressent en les indiquant comme variables numériques
scrutin$Inscr_nbre <- as.numeric(scrutin$Inscrits)
scrutin$Abst_nbre <- as.numeric(scrutin$Abstentions)
scrutin$Votants_nbre <- as.numeric(scrutin$Votants)
scrutin$Expr_nbre <- as.numeric(scrutin$Exprimés)
# Calculs de quelques variables, les pourcentages sont calculés à partir du nombre d'inscrits ou du nombre de votants (pour les blancs, nuls, les candidats etc)
scrutin$Abst_prct_insc <- round(100 * scrutin$Abst_nbre / scrutin$Inscr_nbre, 2)
scrutin$Expr_prct_insc <- round(100 * scrutin$Expr_nbre / scrutin$Inscr_nbre, 2)
scrutin$Votants_prct_insc <- round(100 * scrutin$Votants_nbre / scrutin$Inscr_nbre, 2)
# On traite les Blancs et Nuls séparément, besoin de reprendre la boucle réalisée plus haut si on veut utiliser des données antérieures à 2014
scrutin$Blancs_nbre <- as.numeric(scrutin$Blancs)
scrutin$Nuls_nbre <- as.numeric(scrutin$Nuls)
scrutin$Blancs_prct_insc <- round(100 * scrutin$Blancs_nbre / scrutin$Inscr_nbre, 2)
scrutin$Nuls_prct_insc <- round(100 * scrutin$Nuls_nbre / scrutin$Inscr_nbre, 2)
scrutin$Blancs_prct_vote <- round(100 * scrutin$Blancs_nbre / scrutin$Votants_nbre, 2)
scrutin$Nuls_prct_vote <- round(100 * scrutin$Nuls_nbre / scrutin$Votants_nbre, 2)
candidat <- noms_candidats[1] # Pour tests
for (candidat in noms_candidats) {
# Pour chaque candidat, on veut son nombre de voix
# Traitement par boucle nécessaire surtout pour élections 2017 car les candidats n'ont pas toujours le même numéro de colonne
## Tentative (échec) de fonctionner avec which
# On recherche le numéro de la colonne pour laquelle la valeur est le nom du candidat
# which(scrutin == candidat, arr.ind = TRUE)[, 2]
# On lui ajoute 2 (pour avoir le nombre de voix)
# Et cela donne le score en valeur absolue du candidat en question
# Nécessité de passer par un tableau à part car la fonction wich recherche colonne par colonne et non ligne par ligne donc ordre perturbé
# temp <- as.data.frame(which(scrutin == candidat, arr.ind = TRUE))
# temp <- temp[order(temp$row),]
# scrutin$temp <- temp$col
# On extrait la valeur de la colonne décalée de 2 pour le nom du candidat, pour avoir le nombre de voix
# scrutin[, paste0("nb_voix_", candidat)] <- scrutin[scrutin$temp+2][1]
# Problème si ce n'est pas la même colonne
ligne <- 1285
## Fonctionnement par boucle
for (ligne in 1:nrow(scrutin)) {
scrutin[ligne, paste0("nbre_voix_", candidat)] <- as.numeric(scrutin[ligne, which(scrutin[ligne,] == candidat, arr.ind = TRUE)[, 2]+2]) # Ne marche pas car il y a une géométrie dans le df
# scrutin[ligne, paste0("nbre_voix_", candidat)] <- as.numeric(scrutin[ligne, which(as.logical(scrutin[ligne,] == candidat, arr.ind = TRUE))+2]) # Essai lorsqu'il y avait des géométries, marchait pas complètement
# scrutin[1285,]
} # Fin boucle par ligne pour nombre voix
scrutin[, paste0("prct_expr_", candidat)] <- round(100 * scrutin[, paste0("nbre_voix_", candidat)] / scrutin$Expr_nbre, 2)
scrutin[, paste0("prct_insc_", candidat)] <- round(100 * scrutin[, paste0("nbre_voix_", candidat)] / scrutin$Inscr_nbre, 2)
} # Fin boucle par candidat
scrutin <- scrutin[, c(dim_tabl:ncol(scrutin))]
# Export pour sauvegarde
write.table(scrutin, paste0("data/elections/", nom_scrutin, "_Cfus.csv"), sep="\t", dec = ",", row.names=FALSE)
assign(nom_scrutin, scrutin)
}
# Pour vérifier quelques données manuellement
test_brut <- subset(PR2017_T1_BVot_brut, PR2017_T1_BVot_brut$`Libellé de la commune` == "Orléans")
test <- subset(PR2017_T1_BVot, PR2017_T1_BVot$CODGEO == "45234")
test <- subset(PR2017_T1_BVot_brut, PR2017_T1_BVot_brut$`Libellé de la commune` == "Arboys en Bugey")
test2 <- subset(df2011_PR2017_T1, df2011_PR2017_T1$LIBGEO_new == "Arboys en Bugey")
L’objectif ici est d’avoir, pour chaque commune du df2011, les données électorales pour au moins les élections présidentielles.
Pour cela, il s’agit de traiter différemment les communes, en s’appuyant prioritairement sur les données à l’échelle communale, plus simples à manipuler et permettant davantage un suivi :
pour les communes n’ayant pas connu de fusion, le plus pertinent est de partir des résultats à l’échelle communale ;
pour les communes ayant connu une fusion mais seulement après la date des élections, l’échelle communale également est la plus pertinente et disponible à l’élection donnée ;
pour les communes ayant connu une fusion avant l’élection présidentielle en question, on dispose pour certaines des données à l’échelle des bureaux de vote, ce qui permet de reconstituer les votes ; pour celles dont on ne pourrait pas reconstituer les votes, on les écarte dans un premier temps.
noms_scrutins_presid_jonction <- c("PR2017_T1", "PR2017_T2", "PR2022_T1")
nom_scrutin <- noms_scrutins_presid_jonction[3]
df2011 <- df2011[, c("CODGEO", "LIBGEO", "CODGEO_new", "LIBGEO_new", "CODE_DEPT", "REG", "CATAEU2010", "FusDate", "FusPhas", "COM_NOUV", "ChefLieu", "P09_POP")]
# Import données
for (nom_scrutin in noms_scrutins_presid_jonction) {
annee <- substr(nom_scrutin, start = 3, stop = 6)
# Import des données communales
scrutin_communes <- read.table(paste0("data/elections/", nom_scrutin, ".csv"),
sep="\t", colClasses = "character", head = TRUE, stringsAsFactors = TRUE)
# On refait l'import maintenant qu'on connaît la longueur du tableau, en spécifiant le type de données
scrutin_communes <- read.table(paste0("data/elections/", nom_scrutin, ".csv"),
sep="\t",
colClasses = c(rep("character", 2), rep("numeric", length(scrutin_communes) -2)),
head = TRUE, stringsAsFactors = TRUE, dec =",")
# Import des données par bureaux de vote pour les communes fusionnantes
scrutin_BV <- read.table(paste0("data/elections/", nom_scrutin, "_BVot_Cfus.csv"),
sep="\t", colClasses = "character", head = TRUE, stringsAsFactors = TRUE)
# On refait l'import maintenant qu'on connaît la longueur du tableau, en spécifiant le type de données
scrutin_BV <- read.table(paste0("data/elections/", nom_scrutin, "_BVot_Cfus.csv"),
sep="\t",
colClasses = c(rep("character", 14), rep("numeric", length(scrutin_BV) -14)),
head = TRUE, stringsAsFactors = TRUE, dec =",")
# Pour les communes n'ayant pas connu de fusion, on peut s'appuyer sur les données communales
scrutin_Nfus <- subset(df2011, df2011$COM_NOUV == "NON")
scrutin_Nfus <- merge(scrutin_Nfus, scrutin_communes, by = "CODGEO") # Perte de quelques communes (11), principalement des communes ayant fusionné puis défusionné
# colnames(scrutin_Nfus) # Pour vérifications
# Pour les communes ayant connu une fusion après les élections en question
scrutin_Cfus_apres <- subset(df2011, df2011$COM_NOUV == "OUI" & df2011$FusDate > paste0(annee, "-05-01"))
scrutin_Cfus_apres <- merge(scrutin_Cfus_apres, scrutin_communes, by = "CODGEO")
# colnames(scrutin_Cfus_apres) # Pour vérifications
# Pour les communes ayant connu une fusion avant les élections en question
scrutin_Cfus_avant <- subset(df2011, df2011$COM_NOUV == "OUI" & df2011$FusDate < paste0(annee, "-05-01"))
scrutin_Cfus_avant <- merge(scrutin_Cfus_avant,
scrutin_BV[, c("CODGEO", colnames(scrutin_BV)[14:ncol(scrutin_BV)])],
by = "CODGEO")
# colnames(scrutin_Cfus_avant) # Pour vérifications
print(paste0("Pour le scrutin ", nom_scrutin, ", perte de ",
nrow(subset(df2011, df2011$COM_NOUV == "OUI" & df2011$FusDate < paste0(annee, "-05-01"))) - nrow(scrutin_Cfus_avant)
, " communes fusionnantes du fait des difficultés de jonction pour les données des bureaux de vote."))
scrutin <- bind_rows (scrutin_Cfus_avant, scrutin_Cfus_apres)
# colnames(scrutin) # Pour vérifications
scrutin <- bind_rows (scrutin, scrutin_Nfus)
# colnames(scrutin) # Pour vérifications
scrutin <- subset(scrutin, select = -Code_Dep) # Colonne inutile ici, fait doublon
print(paste0("Au final, pour le scrutin ", nom_scrutin, ", les données sont manquantes pour ",
nrow(df2011) - nrow(scrutin)
, " communes à la géométrie 2011."))
write.table(scrutin, paste0("data/elections/", nom_scrutin, "_geom2011.csv"), sep="\t", dec = ",", row.names=FALSE)
assign(paste0("df2011_", nom_scrutin), scrutin)
}
# Si besoin de vérifier un élément
# scrutin_communes <- read.table(paste0("data/elections/", nom_scrutin, "_geom2011.csv"),
# sep="\t", colClasses = "character", head = TRUE, stringsAsFactors = TRUE)
# scrutin_communes <- read.table(paste0("data/elections/", "PR2017_T1", "_geom2011.csv"),
# sep="\t", colClasses = "character", head = TRUE, stringsAsFactors = TRUE)
NB : État des lieux au 17 mai 2025 :
“Pour le scrutin PR2017_T1, perte de 319 communes fusionnantes du fait des difficultés de jonction pour les données des bureaux de vote.”
“Au final, pour le scrutin PR2017_T1, les données sont manquantes pour 332 communes à la géométrie 2011.”
“Pour le scrutin PR2017_T2, perte de 319 communes fusionnantes du fait des difficultés de jonction pour les données des bureaux de vote.”
“Au final, pour le scrutin PR2017_T2, les données sont manquantes pour 332 communes à la géométrie 2011.”
“Pour le scrutin PR2022_T1, perte de 428 communes fusionnantes du fait des difficultés de jonction pour les données des bureaux de vote.”
“Au final, pour le scrutin PR2022_T1, les données sont manquantes pour 441 communes à la géométrie 2011.”
Il s’agit des données officielles, publiées à l’échelle des communes existant au moment des élections, simplement mises en formes.
# noms_scrutins_presid <- c("PR2012_T1", "PR2012_T2", "PR2017_T1", "PR2017_T2", "PR2022_T1", "PR2022_T2", "PR2017_T1_BVot", "PR2017_T2_BVot", "PR2022_T1_BVot")
noms_scrutins_presid <- c("PR2012_T1", "PR2012_T2", "PR2017_T1", "PR2017_T2", "PR2022_T1", "PR2022_T2")
nom_scrutin <- noms_scrutins_presid[5]
nom_scrutin <- "PR2022_T1_BVot_Cfus"
# Import données
for (nom_scrutin in noms_scrutins_presid) {
scrutin <- read.table(paste0("data/elections/", nom_scrutin, ".csv"),
sep="\t", colClasses = "character", head = TRUE, stringsAsFactors = TRUE)
# On refait l'import maintenant qu'on connaît la longueur du tableau, en spécifiant le type de données
scrutin <- read.table(paste0("data/elections/", nom_scrutin, ".csv"),
sep="\t",
colClasses = c(rep("character", 2), rep("numeric", length(scrutin) -2)),
head = TRUE, stringsAsFactors = TRUE, dec =",")
assign(nom_scrutin, scrutin)
}
rm(scrutin, nom_scrutin)
Il s’agit des données concernant les communes fusionnantes qui ont dû être recalculées à l’aide des bureaux de vote (les communes fusionnant après ne sont pas comprises).
noms_scrutins_presid_Cfus <- c("PR2017_T1_BVot_Cfus", "PR2017_T2_BVot_Cfus", "PR2022_T1_BVot_Cfus")
nom_scrutin <- noms_scrutins_presid_Cfus[2]
# Import données concernant les communes fusionnantes à partir des bureaux de vote
for (nom_scrutin in noms_scrutins_presid_Cfus) {
scrutin <- read.table(paste0("data/elections/", nom_scrutin, ".csv"),
sep="\t", colClasses = "character", head = TRUE, stringsAsFactors = TRUE)
# On refait l'import maintenant qu'on connaît la longueur du tableau, en spécifiant le type de données
scrutin <- read.table(paste0("data/elections/", nom_scrutin, ".csv"),
sep="\t",
colClasses = c(rep("character", 14), rep("numeric", length(scrutin) -14)),
head = TRUE, stringsAsFactors = TRUE, dec =",")
assign(nom_scrutin, scrutin)
}
rm(scrutin, nom_scrutin)
Données qui compilent des résultats parfois à l’échelle communale et parfois à l’échelle des bureaux de vote pour avoir la maille la plus adaptée possible à l’étude des communes nouvelles.
noms_scrutins_presid_df2011 <- c("PR2017_T1", "PR2017_T2", "PR2022_T1")
nom_scrutin <- noms_scrutins_presid_df2011[1]
# Import données concernant les communes fusionnantes à partir des bureaux de vote
for (nom_scrutin in noms_scrutins_presid_df2011) {
scrutin <- read.table(paste0("data/elections/", nom_scrutin, "_geom2011.csv"),
sep="\t", colClasses = "character", head = TRUE, stringsAsFactors = TRUE)
colnames(scrutin) # Pour vérifications
# scrutin[13:length(scrutin)] <- lapply(scrutin[13:length(scrutin)], as.numeric) # Si on veut juste passer certaines colonnes en numérique
# On refait l'import maintenant qu'on connaît la longueur du tableau, en spécifiant le type de données
# Ne marche pas ici ?
scrutin <- read.table(paste0("data/elections/", nom_scrutin, "_geom2011.csv"),
sep="\t",
colClasses = c(rep("character", 13), rep("numeric", length(scrutin) -13)),
head = TRUE, stringsAsFactors = TRUE, dec =",")
assign(paste0("df2011_", nom_scrutin), scrutin)
}
rm(scrutin, nom_scrutin)
# PR2012_T1 <- read.table("data/elections/PR2012_T1.csv",
# sep="\t", colClasses = "character", head = TRUE, stringsAsFactors = TRUE)
# PR2012_T2 <- read.table("data/elections/PR2012_T2.csv",
# sep="\t", colClasses = "character", head = TRUE, stringsAsFactors = TRUE)
# Import des géométries des bureaux de vote
geom_bureaux <- st_read("data/elections/bureaux.gpkg", layer = "bureaux", quiet = TRUE)
carto <- subset(PR2017_T1_BVot_Cfus, PR2017_T1_BVot_Cfus$LIBGEO_new == "Annecy")
carto <- subset(PR2017_T1_BVot_Cfus, PR2017_T1_BVot_Cfus$CODE_DEPT == "74")
carto <- subset(df2011_PR2017_T1, df2011_PR2017_T1$CODE_DEPT == "49")
carto <- subset(df2011_PR2017_T1, df2011_PR2017_T1$CODE_DEPT == "61")
carto <- subset(df2011_PR2017_T1, df2011_PR2017_T1$CODE_DEPT == "74")
carto <- merge(geom2011, carto, all.x = FALSE, all.y = TRUE, by = "CODGEO")
choroLayer(x = carto , var = "prct_expr_MACRON",
method = "quantile", nclass = 6,
col = carto.pal(pal1 = "blue.pal", pal2 = "red.pal", n1 = 3, n2 = 3),
border = NA,
legend.pos = "topleft", legend.values.rnd = 2,
legend.title.txt = "Le vote Macron en 2017")
plot(geomCN_new, add = TRUE, color = NA, lwd = 2)
# labelLayer(carto, txt = "LIBGEO", halo = TRUE, overlap = FALSE, cex = 0.6)
labelLayer(subset(carto, carto$LIBGEO_new == "Annecy"), txt = "LIBGEO", halo = TRUE, overlap = FALSE, cex = 0.6)
choroLayer(x = carto , var = "prct_expr_FILLON",
method = "quantile", nclass = 6,
col = carto.pal(pal1 = "blue.pal", pal2 = "red.pal", n1 = 3, n2 = 3),
border = NA,
legend.pos = "topleft", legend.values.rnd = 2,
legend.title.txt = "Le vote Macron en 2017")
plot(geomCN_new, add = TRUE, color = NA, lwd = 2)
# labelLayer(carto, txt = "LIBGEO", halo = TRUE, overlap = FALSE, cex = 0.6)
labelLayer(subset(carto, carto$LIBGEO_new == "Annecy"), txt = "LIBGEO", halo = TRUE, overlap = FALSE, cex = 0.6)
# Limite à mettre si on veut empêcher la mise en cache de la typologie etc.
knitr::opts_chunk$set(echo=TRUE, # Afficher ou non le code R dans le document
eval = TRUE, # Exécuter ou non le code R à la compilation
include = TRUE, # Inclure ou non le code R et ses résultats dans le document
# results “hide”/“asis”/“markup”/“hold” Type de résultats renvoyés par le bloc de code
warning = TRUE, # Afficher ou non les avertissements générés par le bloc
message = TRUE, # Afficher ou non les messages générés par le bloc
cache = FALSE) # Utiliser le cache pour accélerer les knits.
Durant la soutenance de la thèse (6 décembre 2024), Jean Rivière a évoqué l’intérêt que représenterait l’étude de la participation et de l’abstention lors des élections municipales. Les lignes suivantes proposent une première analyse exploratoire.
# Import des données générales et socio-économiques
load("data/refdata.Rdata")
# load("Archives/data_prep 2011-2020(01)/data/refdata.Rdata")
# Import des géométries
geomfus2011 <- st_read("data/geom.gpkg", layer = "geomfus2011", quiet = TRUE) # Les communes qui ont participé à la création de communes nouvelles (appelées communes fusionnantes).
geom2011 <- st_read("data/geom.gpkg", layer = "geom2011", quiet = TRUE)
geomCN_new <- st_read("data/geom.gpkg", layer = "geomCN_new", quiet = TRUE)
geom_new <- st_read("data/geom.gpkg", layer = "geom_new", quiet = TRUE)
dep <- st_read("data/geom.gpkg", layer = "dep", quiet = TRUE) # Départements
# Import des données sur la participation au 1er tour des municipales de 2014
Munic2014T1 <- read.table("data/elections/Municipales2014_T1_abstention.csv", sep="\t", colClasses = "character", head = TRUE, stringsAsFactors = TRUE)
sapply(Munic2014T1, class)
## CODGEO LIBSUBCOM NBRINS NBRABS NBREXP PCTVOTINS
## "character" "character" "character" "character" "character" "character"
## PCTABSINS PCTEXPINS type_comm
## "character" "character" "character"
Munic2014T1[3:8] <- lapply(Munic2014T1[3:8], as.numeric)
colnames(Munic2014T1) <- paste0 (colnames(Munic2014T1), "_2014")
df2011_abst <- merge(df2011[c("CODGEO", "LIBGEO", "CODE_DEPT", "CATAEU2010", "COM_NOUV", "FusDate", "CODGEO_new")],
Munic2014T1, by.x = "CODGEO", by.y = "CODGEO_2014", all.x = TRUE, suffixes = c("", "_2014"))
# Un nombre conséquent de communes ne sont pas renseignées
donnees_manquantes <- subset(df2011_abst, is.na(df2011_abst$LIBSUBCOM_2014))
table(df2011$COM_NOUV)
##
## NON OUI
## 33537 2671
table(donnees_manquantes$COM_NOUV)
##
## NON OUI
## 1350 79
# Les proportions sont similaires, les données manquantes ne paraissent pas corrélées au fait d'appartenir ou non à une commune nouvelle, on peut donc poursuivre l'analyse
# table(df2011_abst$COM_NOUV, df2011_abst$PCTVOTINS_2014)
# Import des données sur la participation au 1er tour des municipales de 2020
Munic2020T1 <- read.table("data/elections/Municipales2020_T1_abstention.csv", sep="\t",
head = TRUE, stringsAsFactors = TRUE)
# On recalcule les pourcentages pour qu'ils soient en variable numérique
Munic2020T1$PCTVOTINS <- round(100 * (Munic2020T1$NBRINS - Munic2020T1$NBRABS) / Munic2020T1$NBRINS,2)
Munic2020T1$PCTABSINS <- round(100 * Munic2020T1$NBRABS / Munic2020T1$NBRINS, 2)
Munic2020T1$PCTEXPINS <- round(100 * Munic2020T1$NBREXP / Munic2020T1$NBRINS, 2)
colnames(Munic2020T1) <- paste0 (colnames(Munic2020T1), "_2020")
sapply(Munic2020T1, class)
## CODGEO_2020 LIBSUBCOM_2020 NBRINS_2020 NBRABS_2020 NBREXP_2020
## "factor" "factor" "integer" "integer" "integer"
## PCTVOTINS_2020 PCTABSINS_2020 PCTEXPINS_2020 type_comm_2020
## "numeric" "numeric" "numeric" "factor"
Munic2020T1[3:8] <- lapply(Munic2020T1[3:8], as.numeric)
df_new_abst <- merge(df_new[c("CODGEO_new", "LIBGEO_new", "CODE_DEPT_new", "CATAEU2010", "COM_NOUV", "FusDate")],
Munic2020T1, by.x = "CODGEO_new", by.y = "CODGEO_2020", all.x = TRUE, suffixes = c("", "_2020"))
donnees_manquantes <- subset(df_new_abst, is.na(df_new_abst$LIBSUBCOM_2020))
table(df_new_abst$COM_NOUV)
##
## NON OUI
## 33532 847
table(donnees_manquantes$COM_NOUV)
##
## NON OUI
## 3008 168
NB : Les communes nouvelles sont sur-représentées dans les données manquantes si on comptabilise les fusions jusqu’au 1er janvier 2025 mais aussi si on ne prend en compte que les fusions jusqu’au 1er janvier 2020. Il faut donc être particulièrement précautionneux dans les interprétations des analyses.
variables_abstention <- c("NBRINS_2014", "NBRABS_2014", "NBREXP_2014", "PCTVOTINS_2014", "PCTABSINS_2014", "PCTEXPINS_2014")
noms_variables <- c("Nombre d'inscrits sur les listes électorales", "Nombre d'abstentionnistes", "Nombre de suffrages exprimés", "Pourcentage de votants par rapport au nombre d'inscrits", "Pourcentage d'abstentionnistes par rapport au nombre d'inscrits", "Pourcentage de suffrages exprimés par rapport au nombre d'inscrits")
labels_COM_NOUV <- c("Communes non fusionnantes", "Communes fusionnantes")
couleurs <- c("#2b83ba", "red4")
variable <- variables_abstention[1]
for (variable in variables_abstention) {
nom_variable <- noms_variables[which(variables_abstention == variable)]
boxplot <- ggplot(df2011_abst, aes(x = COM_NOUV, y = df2011_abst[, variable], fill = COM_NOUV, color = COM_NOUV)) +
geom_boxplot(width = 1.5, varwidth = TRUE) +
scale_color_manual(values=couleurs , labels = labels_COM_NOUV) +
scale_fill_manual(values = c("white", "white", "white"), labels = labels_COM_NOUV) +
labs(fill = " ", color = " ") +
ylab(nom_variable) +
xlab("Statut de la commune") +
ggtitle(paste0(nom_variable, "\nen fonction du statut communal (2014)"))+
# coord_cartesian(ylim=c(lower.limit, upper.limit)) +
theme(axis.text.x = element_text(angle = 45, hjust = 1, size = 10), legend.position = "right")
print (boxplot)
# On modifie éventuellement le graphique pour le rendre plus lisible si valeurs extrêmes
# upper.limit <- quantile(df2011_abst[, variable], na.rm = TRUE)[4] + 4*IQR(df2011_abst[, variable], na.rm = TRUE)
# lower.limit <- quantile(df2011_abst[, variable], na.rm = TRUE)[2] - 4*IQR(df2011_abst[, variable], na.rm = TRUE)
# print (boxplot + coord_cartesian(ylim=c(lower.limit, upper.limit)))
# print (boxplot + coord_cartesian(ylim=c(, upper.limit)))
}
variables_abstention <- c("NBRINS_2020", "NBRABS_2020", "NBREXP_2020", "PCTVOTINS_2020", "PCTABSINS_2020", "PCTEXPINS_2020")
noms_variables <- c("Nombre d'inscrits sur les listes électorales", "Nombre d'abstentionnistes", "Nombre de suffrages exprimés", "Pourcentage de votants par rapport au nombre d'inscrits", "Pourcentage d'abstentionnistes par rapport au nombre d'inscrits", "Pourcentage de suffrages exprimés par rapport au nombre d'inscrits")
labels_COM_NOUV <- c("Communes non fusionnantes", "Communes fusionnantes")
couleurs <- c("#2b83ba", "red4")
variable <- variables_abstention[1]
for (variable in variables_abstention) {
nom_variable <- noms_variables[which(variables_abstention == variable)]
boxplot <- ggplot(df_new_abst, aes(x = COM_NOUV, y = df_new_abst[, variable], fill = COM_NOUV, color = COM_NOUV)) +
geom_boxplot(width = 1.5, varwidth = TRUE) +
scale_color_manual(values=couleurs , labels = labels_COM_NOUV) +
scale_fill_manual(values = c("white", "white", "white"), labels = labels_COM_NOUV) +
labs(fill = " ", color = " ") +
ylab(nom_variable) +
xlab("Statut de la commune") +
ggtitle(paste0(nom_variable, "\nen fonction du statut communal (2020)"))+
# coord_cartesian(ylim=c(lower.limit, upper.limit)) +
theme(axis.text.x = element_text(angle = 45, hjust = 1, size = 10), legend.position = "right")
print (boxplot)
# On modifie éventuellement le graphique pour le rendre plus lisible si valeurs extrêmes
# upper.limit <- quantile(df_new_abst[, variable], na.rm = TRUE)[4] + 4*IQR(df_new_abst[, variable], na.rm = TRUE)
# lower.limit <- quantile(df_new_abst[, variable], na.rm = TRUE)[2] - 4*IQR(df_new_abst[, variable], na.rm = TRUE)
# print (boxplot + coord_cartesian(ylim=c(lower.limit, upper.limit)))
# print (boxplot + coord_cartesian(ylim=c(, upper.limit)))
}
On veut un tableau ou, pour les communes nouvelles, on puisse avoir le pourcentage d’abstention en 2014 et en 2020. Implique d’agréger les données.
On utilise la fonction réalisée pour la base DAC (Données Agrégées des Communes), cf. data paper publié par G. Bideau et R. Ysebaert.
comix <- function(x, xid, app, app.init, app.target, var, var.type, w = NULL, na.rm = FALSE) {
# Supprimer les géométries s'il y en a
if (methods::is(x, "sf")){
x <- st_set_geometry(x, NULL)
}
# Import table d'appartenance des fusions territoriales
app <- app
# Jointure table d'entrée - table des fusions territoriales
x <- merge(x, app[,c(app.init, app.target)], by.x = xid, by.y = app.init, all.x = TRUE)
# Unités non concernées par modifications
tmp <- aggregate(x[,app.target], by = list(app.target = x[,app.target]), FUN = length)
tmp <- tmp[tmp$x <= 1,]
selecUnit <- tmp$app.target
intact <- x[x[,app.target] %in% selecUnit, ]
intact <- intact[, c(app.target, var)]
# Unités concernées par une modification
modif <- x[!x[,app.target]%in% selecUnit, ]
modif <- modif[, c(app.target, var, w)]
# Gestion des types de variables déclarées
tmp <- data.frame(var, var.type, row.names = var)
txt <- row.names(tmp[tmp$var.type == "text",])
stock <- row.names(tmp[tmp$var.type == "stock",])
ratio <- row.names(tmp[tmp$var.type == "ratio",])
# Si variables de type caractère > concaténation des modalités
if(length(txt > 0)){
modif.t <- modif[,c(app.target, txt)]
modif.t <- aggregate(modif.t[, -1],
by = list(app.target = modif.t[,app.target]),
FUN = function(x) {paste0(unique(x), collapse = "-")})
names(modif.t) <- c(app.target, txt)
}
# Si variables de type stock > somme des valeurs
if(length(stock > 0)){
modif.s <- modif[,c(app.target, stock)]
modif.s <- aggregate(modif.s[, -1],
by = list(app.target = modif.s[,app.target]),
FUN = sum, na.rm = na.rm)
names(modif.s) <- c(app.target, stock)
}
# Si variables de type ratio > moyenne simple ou pondérée
## Si pas de variable de pondération
if(length(ratio > 0)){
if(is.null(w)){
modif.r <- modif[,c(app.target, ratio)]
modif.r <- aggregate(modif.r[, -1],
by = list(CODGEO_new = modif.r$CODGEO_new),
FUN = mean, na.rm = na.rm)
}
## Si pondération...
# Commentaire : Avec dplyr, fonctionnement pas très esthétique mais fonctionne.
# Plusieurs méthodes non concluantes ont été testées (cf sous la fonction)
else{
modif.r <- modif[,c(app.target, ratio, w)]
names(modif.r)[which(names(modif.r) == w)] <- "weight"
names(modif.r)[which(names(modif.r) == app.target)] <- "app.target"
names(modif.r)[which(names(modif.r) %in% ratio)] <- paste0("ratio",names(modif.r[ratio]))
modif.r <- modif.r %>%
group_by_at(vars(app.target)) %>%
summarise_at(vars(starts_with('ratio')), list(~weighted.mean(., weight, na.rm = na.rm)))
modif.r <- as.data.frame(modif.r)
}
names(modif.r) <- c(app.target, ratio)
}
# Union des 3 types de variables - 8 cas de figure
# Commentaire : pas trouvé la solution du type if(exists("x")), cbind(x)
if(exists("modif.t") == FALSE & exists("modif.s") == FALSE & exists("modif.r") == FALSE ){
stop("Define at least one var combined to one var.type", call. = FALSE)
}
if(exists("modif.t") == TRUE & exists("modif.s") == TRUE & exists("modif.r") == TRUE ){
modif <- cbind(modif.t, modif.s, modif.r)
}
if(exists("modif.t") == FALSE & exists("modif.s") == TRUE & exists("modif.r") == TRUE ){
modif <- cbind(modif.s, modif.r)
}
if(exists("modif.t") == TRUE & exists("modif.s") == FALSE & exists("modif.r") == TRUE){
modif <- cbind(modif.t, modif.r)
}
if(exists("modif.t") == TRUE & exists("modif.s") == TRUE & exists("modif.r") == FALSE){
modif <- cbind(modif.t, modif.s)
}
if(exists("modif.t") == TRUE & exists("modif.s") == FALSE & exists("modif.r") == FALSE){
modif <- modif.t
}
if(exists("modif.t") == FALSE & exists("modif.s") == TRUE & exists("modif.r") == FALSE){
modif <- modif.s
}
if(exists("modif.t") == FALSE & exists("modif.s") == FALSE & exists("modif.r") == TRUE){
modif <- modif.r
}
# Liaison avec les unités territoriales inchangées
x <- rbind(intact, modif[,names(intact)])
return(x)
}
# Import des données concernant les tables de passage pour pouvoir agréger les données possible, mais pas nécessaire (cf. ligne plus bas)
# # Création de la table de passage (cf. script data_prep pour plus de détails)
# comSci <- data.frame(read_excel("data-raw/communes_nouvelles/table_passage_geo2003_geo2025.xlsx", sheet = "Liste des scissions", skip = 5))
# modif <- as.data.frame(read_xlsx("data-raw/communes_nouvelles/table_passage_geo2003_geo2025.xlsx", col_types = "text", sheet = "Table de passage", skip = 5))
# colnames(modif) <- c("CODGEO_INI", "CODGEO_new", "LIBGEO_new" )
# pr_suppr_doublons <- subset (comSci, comSci$COM_INI != comSci$COM_FIN)
# # Création d'un champ concaténant les deux CODGEO en question
# pr_suppr_doublons$conc <- paste(pr_suppr_doublons$COM_INI, "-", pr_suppr_doublons$COM_FIN)
# modif$conc <- paste(modif$CODGEO_INI, "-", modif$CODGEO_new)
# modif <- subset(modif, !(modif$conc %in% pr_suppr_doublons$conc))
# modif <- modif[,-4]
# On peut partir des données de df2011 pour avoir l'appartenance directement
appartenance <- df2011_abst[, c("CODGEO", "CODGEO_new")]
colnames(appartenance) <- c("CODGEO_INI", "CODGEO_new")
# Création d'un tableau sur le même modèle que dans le *data paper* si besoin (pas utilisé, fait à la main)
# target <- data.frame()
# target <- as.data.frame(c("CODGEO", "NBRABS_2014"))
# colnames(target) <- "recoding"
# target$type_variable <- c("text", "stock")
# Pour simplifier, on ne va prendre que les données en valeurs absolues
colnames(df2011_abst)
# On retire la colonne CODGEO_new qui pose problème pour le traitement de la fonction
df2011_abst <- df2011_abst[-which(colnames(df2011_abst) == "CODGEO_new")]
colnames(df2011_abst)
# Attention à bien indiquer le type de données
tmp <- comix(x = df2011_abst, xid = "CODGEO", app = appartenance,
app.init = "CODGEO_INI", app.target = "CODGEO_new",
var = colnames(df2011_abst)[1:10],
var.type = c(rep("text",7), rep("stock",3)))
colnames(df_new_abst)
# Calcul des pourcentages (à la main car pas de fichier spécifique, contrairement au data paper)
colnames(df2011_abst)
tmp$PCTVOTINS_2014 <- round(100 * (tmp$NBRINS_2014 - tmp$NBRABS_2014) / tmp$NBRINS_2014,2)
tmp$PCTABSINS_2014 <- round(100 * tmp$NBRABS_2014 / tmp$NBRINS_2014, 2)
tmp$PCTEXPINS_2014 <- round(100 * tmp$NBREXP_2014 / tmp$NBRINS_2014, 2)
df_new_abst <- merge (df_new_abst, tmp, by = "CODGEO_new", suffixes = c("", "_2014"))
try(save(df2011_abst, df_new_abst, geom2011, geom_new, geomCN_new, geomfus2011, file = "data/refdata_abst.Rdata"))
load("data/refdata_abst.Rdata")
load("data/refdata_abst.Rdata")
df_reg <- df_new_abst
# Nécessité de passer la variable d'intérêt en facteur pour la fonction glm suivante
df_reg$COM_NOUV <- as.factor(df_reg$COM_NOUV)
class(df_reg$COM_NOUV)
## [1] "factor"
freq(df_reg$COM_NOUV)
## n % val%
## NON 33532 97.5 97.5
## OUI 847 2.5 2.5
# Vérification que la variable la plus fréquente est bien la première (doit être la variable de référence)
freq(df_reg$COM_NOUV, sort = "dec")
## n % val%
## NON 33532 97.5 97.5
## OUI 847 2.5 2.5
row.names(freq(df_reg$COM_NOUV, sort = "dec"))
## [1] "NON" "OUI"
ordre <- row.names(freq(df_reg$COM_NOUV, sort = "dec"))
df_reg$COM_NOUV <- factor (df_reg$COM_NOUV, ordre)
# Si on veut forcer dans un sens :
# df_reg$COM_NOUV <- relevel (df_reg$COM_NOUV, "NON", "OUI")
# Les variables explicatives sont mentionnées juste après la variable d'intérêt (ici, "COM_NOUV")
colnames(df_reg)
## [1] "CODGEO_new" "LIBGEO_new" "CODE_DEPT_new" "CATAEU2010"
## [5] "COM_NOUV" "FusDate" "LIBSUBCOM_2020" "NBRINS_2020"
## [9] "NBRABS_2020" "NBREXP_2020" "PCTVOTINS_2020" "PCTABSINS_2020"
## [13] "PCTEXPINS_2020" "type_comm_2020" "CODGEO" "LIBGEO"
## [17] "CODE_DEPT" "CATAEU2010_2014" "COM_NOUV_2014" "FusDate_2014"
## [21] "LIBSUBCOM_2014" "NBRINS_2014" "NBRABS_2014" "NBREXP_2014"
## [25] "PCTVOTINS_2014" "PCTABSINS_2014" "PCTEXPINS_2014"
reg <- glm(COM_NOUV ~
# CIF_2012_quantiles + CODE_DEPT,
CODE_DEPT_new + CATAEU2010 + NBRINS_2020 + PCTVOTINS_2014 + PCTVOTINS_2020,
# CIF_2012_quantiles,
data = df_reg, family = binomial(logit), na.action = na.exclude)
options(max.print=10000)
summary(reg)
##
## Call:
## glm(formula = COM_NOUV ~ CODE_DEPT_new + CATAEU2010 + NBRINS_2020 +
## PCTVOTINS_2014 + PCTVOTINS_2020, family = binomial(logit),
## data = df_reg, na.action = na.exclude)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -3.094e+00 7.035e-01 -4.399 1.09e-05 ***
## CODE_DEPT_new02 -1.501e+00 7.372e-01 -2.037 0.041685 *
## CODE_DEPT_new03 -1.534e+00 1.103e+00 -1.390 0.164393
## CODE_DEPT_new04 -2.213e-01 8.520e-01 -0.260 0.795071
## CODE_DEPT_new05 -3.832e-02 8.544e-01 -0.045 0.964227
## CODE_DEPT_new06 -1.529e+01 1.152e+03 -0.013 0.989412
## CODE_DEPT_new07 -3.510e-01 7.441e-01 -0.472 0.637115
## CODE_DEPT_new08 -1.059e+00 8.451e-01 -1.253 0.210333
## CODE_DEPT_new09 -3.024e-01 7.450e-01 -0.406 0.684852
## CODE_DEPT_new10 -1.554e+01 5.090e+02 -0.031 0.975640
## CODE_DEPT_new11 -8.635e-01 7.414e-01 -1.165 0.244164
## CODE_DEPT_new12 -3.597e-01 7.457e-01 -0.482 0.629536
## CODE_DEPT_new13 -1.553e+01 1.907e+03 -0.008 0.993504
## CODE_DEPT_new14 5.359e-01 5.105e-01 1.050 0.293795
## CODE_DEPT_new15 3.129e-01 6.917e-01 0.452 0.651007
## CODE_DEPT_new16 2.559e-01 5.537e-01 0.462 0.643976
## CODE_DEPT_new17 -9.081e-01 6.426e-01 -1.413 0.157565
## CODE_DEPT_new18 -1.055e+00 8.453e-01 -1.248 0.211972
## CODE_DEPT_new19 1.684e-01 6.880e-01 0.245 0.806609
## CODE_DEPT_new21 -8.821e-01 6.420e-01 -1.374 0.169478
## CODE_DEPT_new22 2.755e-01 5.995e-01 0.460 0.645802
## CODE_DEPT_new23 -8.185e-01 8.511e-01 -0.962 0.336211
## CODE_DEPT_new24 3.948e-01 5.491e-01 0.719 0.472136
## CODE_DEPT_new25 1.721e-01 5.383e-01 0.320 0.749186
## CODE_DEPT_new26 -2.270e-01 6.448e-01 -0.352 0.724795
## CODE_DEPT_new27 -2.269e-01 5.424e-01 -0.418 0.675785
## CODE_DEPT_new28 -2.619e-01 5.953e-01 -0.440 0.659932
## CODE_DEPT_new29 -9.756e-01 8.475e-01 -1.151 0.249681
## CODE_DEPT_new30 -1.259e+00 1.104e+00 -1.140 0.254088
## CODE_DEPT_new31 -7.556e-01 7.398e-01 -1.021 0.307077
## CODE_DEPT_new32 -1.942e+00 1.104e+00 -1.759 0.078646 .
## CODE_DEPT_new33 -1.796e+00 1.102e+00 -1.630 0.103159
## CODE_DEPT_new34 -1.534e+01 7.682e+02 -0.020 0.984068
## CODE_DEPT_new35 -1.569e+01 9.704e+02 -0.016 0.987099
## CODE_DEPT_new36 -6.488e-01 8.520e-01 -0.762 0.446349
## CODE_DEPT_new37 -1.563e+01 8.277e+02 -0.019 0.984937
## CODE_DEPT_new38 -1.916e-01 5.588e-01 -0.343 0.731771
## CODE_DEPT_new39 5.561e-01 5.390e-01 1.032 0.302267
## CODE_DEPT_new40 -1.534e+01 5.486e+02 -0.028 0.977693
## CODE_DEPT_new41 -2.928e-01 6.809e-01 -0.430 0.667198
## CODE_DEPT_new42 -9.750e-01 7.413e-01 -1.315 0.188435
## CODE_DEPT_new43 -7.578e-01 8.488e-01 -0.893 0.371967
## CODE_DEPT_new44 -2.516e+00 1.450e+00 -1.736 0.082595 .
## CODE_DEPT_new45 -9.493e-01 7.386e-01 -1.285 0.198688
## CODE_DEPT_new46 8.510e-01 5.660e-01 1.504 0.132707
## CODE_DEPT_new47 -1.549e+01 6.126e+02 -0.025 0.979828
## CODE_DEPT_new48 1.794e+00 5.815e-01 3.085 0.002033 **
## CODE_DEPT_new49 1.019e+00 5.505e-01 1.852 0.064090 .
## CODE_DEPT_new50 6.549e-01 5.145e-01 1.273 0.203057
## CODE_DEPT_new51 -1.454e+00 7.393e-01 -1.967 0.049208 *
## CODE_DEPT_new52 -7.219e-01 7.418e-01 -0.973 0.330450
## CODE_DEPT_new53 1.787e-01 5.994e-01 0.298 0.765566
## CODE_DEPT_new54 -2.444e+00 1.100e+00 -2.221 0.026326 *
## CODE_DEPT_new55 -1.920e+00 1.102e+00 -1.742 0.081483 .
## CODE_DEPT_new56 -3.886e-01 7.421e-01 -0.524 0.600498
## CODE_DEPT_new57 -1.434e+00 6.796e-01 -2.110 0.034834 *
## CODE_DEPT_new58 -1.028e+00 8.484e-01 -1.212 0.225411
## CODE_DEPT_new59 -1.929e+00 8.545e-01 -2.257 0.024015 *
## CODE_DEPT_new60 -6.422e-01 5.786e-01 -1.110 0.267049
## CODE_DEPT_new61 2.469e-01 5.719e-01 0.432 0.665941
## CODE_DEPT_new62 -8.813e-01 6.433e-01 -1.370 0.170724
## CODE_DEPT_new63 -7.606e-01 6.807e-01 -1.117 0.263857
## CODE_DEPT_new64 -1.819e+00 1.103e+00 -1.650 0.099011 .
## CODE_DEPT_new65 -2.057e-01 6.457e-01 -0.319 0.750055
## CODE_DEPT_new66 -1.548e+01 7.589e+02 -0.020 0.983724
## CODE_DEPT_new67 -1.231e+00 6.521e-01 -1.888 0.059038 .
## CODE_DEPT_new68 -5.328e-01 6.178e-01 -0.862 0.388435
## CODE_DEPT_new69 -6.286e-01 7.452e-01 -0.844 0.398897
## CODE_DEPT_new70 -9.418e-01 7.397e-01 -1.273 0.202897
## CODE_DEPT_new71 -9.379e-01 6.415e-01 -1.462 0.143714
## CODE_DEPT_new72 -7.752e-01 6.808e-01 -1.139 0.254865
## CODE_DEPT_new73 5.494e-01 5.845e-01 0.940 0.347265
## CODE_DEPT_new74 -2.918e-01 6.830e-01 -0.427 0.669191
## CODE_DEPT_new76 -1.160e+00 6.407e-01 -1.811 0.070208 .
## CODE_DEPT_new77 -1.418e+00 6.806e-01 -2.083 0.037234 *
## CODE_DEPT_new78 -7.520e-01 7.424e-01 -1.013 0.311069
## CODE_DEPT_new79 3.608e-01 5.856e-01 0.616 0.537804
## CODE_DEPT_new80 -1.119e+00 6.798e-01 -1.646 0.099681 .
## CODE_DEPT_new81 -8.786e-01 8.462e-01 -1.038 0.299127
## CODE_DEPT_new82 -1.553e+01 8.142e+02 -0.019 0.984778
## CODE_DEPT_new83 -1.606e+01 1.120e+03 -0.014 0.988561
## CODE_DEPT_new84 -1.551e+01 1.090e+03 -0.014 0.988653
## CODE_DEPT_new85 3.558e-01 6.008e-01 0.592 0.553735
## CODE_DEPT_new86 -3.345e-01 6.820e-01 -0.491 0.623778
## CODE_DEPT_new87 -1.255e+00 1.104e+00 -1.136 0.255941
## CODE_DEPT_new88 -7.805e-01 7.406e-01 -1.054 0.291923
## CODE_DEPT_new89 -7.714e-01 6.795e-01 -1.135 0.256262
## CODE_DEPT_new90 -1.575e+01 1.243e+03 -0.013 0.989887
## CODE_DEPT_new91 -8.637e-01 8.489e-01 -1.017 0.308941
## CODE_DEPT_new95 -7.580e-01 8.493e-01 -0.892 0.372134
## CATAEU2010111-112 2.460e+01 4.241e+03 0.006 0.995372
## CATAEU2010112 1.837e+00 3.505e-01 5.242 1.59e-07 ***
## CATAEU2010112-111 2.533e+01 3.642e+03 0.007 0.994452
## CATAEU2010112-120 2.568e+01 2.170e+03 0.012 0.990556
## CATAEU2010112-120-300 2.517e+01 6.124e+03 0.004 0.996721
## CATAEU2010112-211 2.420e+01 1.075e+04 0.002 0.998205
## CATAEU2010112-221 2.527e+01 1.075e+04 0.002 0.998125
## CATAEU2010112-300 2.535e+01 6.080e+03 0.004 0.996673
## CATAEU2010112-300-111 2.342e+01 1.075e+04 0.002 0.998263
## CATAEU2010112-300-120 2.460e+01 6.014e+03 0.004 0.996736
## CATAEU2010112-300-221-120 2.320e+01 1.075e+04 0.002 0.998279
## CATAEU2010112-300-400 2.396e+01 1.075e+04 0.002 0.998223
## CATAEU2010112-400 2.582e+01 7.381e+03 0.003 0.997209
## CATAEU2010112-400-120 2.644e+01 1.075e+04 0.002 0.998038
## CATAEU2010112-400-300 2.643e+01 1.075e+04 0.002 0.998039
## CATAEU2010112-400-300-222-120 2.402e+01 1.075e+04 0.002 0.998218
## CATAEU2010120 1.682e+00 3.812e-01 4.414 1.02e-05 ***
## CATAEU2010120-111 2.393e+01 1.075e+04 0.002 0.998224
## CATAEU2010120-112 2.552e+01 2.389e+03 0.011 0.991476
## CATAEU2010120-112-300 2.272e+01 1.075e+04 0.002 0.998314
## CATAEU2010120-212 2.475e+01 1.075e+04 0.002 0.998164
## CATAEU2010120-221 2.428e+01 1.075e+04 0.002 0.998198
## CATAEU2010120-221-300 2.388e+01 1.075e+04 0.002 0.998228
## CATAEU2010120-221-300-222 2.395e+01 1.075e+04 0.002 0.998223
## CATAEU2010120-300 2.571e+01 3.612e+03 0.007 0.994320
## CATAEU2010120-300-112 2.460e+01 1.075e+04 0.002 0.998175
## CATAEU2010120-300-221 2.350e+01 7.354e+03 0.003 0.997450
## CATAEU2010120-300-400 2.534e+01 1.075e+04 0.002 0.998120
## CATAEU2010120-400 2.532e+01 4.592e+03 0.006 0.995601
## CATAEU2010211 -1.382e+01 5.956e+02 -0.023 0.981486
## CATAEU2010212 1.662e+00 4.924e-01 3.375 0.000738 ***
## CATAEU2010212-211 2.464e+01 5.304e+03 0.005 0.996293
## CATAEU2010212-211-300 2.392e+01 1.075e+04 0.002 0.998225
## CATAEU2010212-221 2.445e+01 1.075e+04 0.002 0.998186
## CATAEU2010212-300 3.808e+01 3.407e+03 0.011 0.991082
## CATAEU2010212-300-221 2.415e+01 1.075e+04 0.002 0.998209
## CATAEU2010212-400 2.425e+01 1.075e+04 0.002 0.998201
## CATAEU2010212-400-300-211 2.381e+01 1.075e+04 0.002 0.998234
## CATAEU2010221 1.036e+00 5.651e-01 1.834 0.066727 .
## CATAEU2010221-120 2.490e+01 1.075e+04 0.002 0.998152
## CATAEU2010221-212-300 2.351e+01 1.075e+04 0.002 0.998256
## CATAEU2010221-222 2.465e+01 6.112e+03 0.004 0.996782
## CATAEU2010221-222-300 2.364e+01 1.075e+04 0.002 0.998246
## CATAEU2010221-300 2.514e+01 7.418e+03 0.003 0.997295
## CATAEU2010222 9.468e-02 1.066e+00 0.089 0.929226
## CATAEU2010222-221 2.381e+01 1.075e+04 0.002 0.998233
## CATAEU2010222-300 2.567e+01 5.206e+03 0.005 0.996066
## CATAEU2010300 1.591e+00 3.793e-01 4.194 2.74e-05 ***
## CATAEU2010300-112 3.770e+01 3.353e+03 0.011 0.991029
## CATAEU2010300-120 2.532e+01 3.296e+03 0.008 0.993871
## CATAEU2010300-120-112 2.417e+01 1.075e+04 0.002 0.998207
## CATAEU2010300-120-221 2.691e+01 7.489e+03 0.004 0.997133
## CATAEU2010300-120-221-400 2.332e+01 1.075e+04 0.002 0.998270
## CATAEU2010300-120-400 2.408e+01 1.075e+04 0.002 0.998213
## CATAEU2010300-211 2.431e+01 7.466e+03 0.003 0.997402
## CATAEU2010300-212 2.497e+01 5.287e+03 0.005 0.996231
## CATAEU2010300-212-211 2.282e+01 1.075e+04 0.002 0.998307
## CATAEU2010300-212-400 2.418e+01 1.075e+04 0.002 0.998206
## CATAEU2010300-221 3.708e+01 2.055e+03 0.018 0.985607
## CATAEU2010300-221-212 2.351e+01 1.075e+04 0.002 0.998256
## CATAEU2010300-222 2.614e+01 4.468e+03 0.006 0.995331
## CATAEU2010300-400 3.622e+01 1.743e+03 0.021 0.983424
## CATAEU2010300-400-212 2.486e+01 1.075e+04 0.002 0.998156
## CATAEU2010300-400-221 2.453e+01 6.133e+03 0.004 0.996809
## CATAEU2010400 2.331e+00 3.712e-01 6.278 3.42e-10 ***
## CATAEU2010400-112 2.812e+01 1.075e+04 0.003 0.997914
## CATAEU2010400-120 2.577e+01 5.167e+03 0.005 0.996021
## CATAEU2010400-120-300 2.383e+01 1.075e+04 0.002 0.998232
## CATAEU2010400-212 2.570e+01 1.075e+04 0.002 0.998093
## CATAEU2010400-221 2.420e+01 7.421e+03 0.003 0.997398
## CATAEU2010400-221-300 2.547e+01 1.075e+04 0.002 0.998110
## CATAEU2010400-222 2.411e+01 1.075e+04 0.002 0.998211
## CATAEU2010400-300 2.536e+01 1.678e+03 0.015 0.987945
## CATAEU2010400-300-212 2.456e+01 1.075e+04 0.002 0.998178
## CATAEU2010400-300-221 2.322e+01 1.075e+04 0.002 0.998278
## NBRINS_2020 4.100e-05 7.672e-06 5.343 9.13e-08 ***
## PCTVOTINS_2014 6.117e-03 7.650e-03 0.800 0.423913
## PCTVOTINS_2020 -5.328e-02 5.572e-03 -9.561 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 6173.8 on 30132 degrees of freedom
## Residual deviance: 3575.3 on 29965 degrees of freedom
## (4246 observations effacées parce que manquantes)
## AIC: 3911.3
##
## Number of Fisher Scoring iterations: 18
# exp(coef(reg))
# exp(confint(reg))
# exp(cbind(coef(reg), confint(reg)))
# odds.ratio(reg)
# Pour vérifier les VIF
# car::vif(reg)
# which(car::vif(reg)[,3] > 1.9)
# test <- as.data.frame(car::vif(reg))
# Présentation d'un tableau plus propre
# tbl_regression(reg, exponentiate = TRUE)
# add_vif(tbl_regression(reg, exponentiate = TRUE)) # Avec affichage des VIF
# Représentations graphiques du modèle
# ggcoef_model(reg, exponentiate = FALSE)
# forest_model(reg)
Cette analyse exploratoire (mériterait d’être approfondie, par exemple car le champ “CATAEU2010” est composé de concaténation pour une partie des communes nouvelles) montre que la participation en 2020 est significativement plus faible en 2020 dans les communes nouvelles, y compris si on contrôle (« Toutes choses étant égales par ailleurs quant aux variables étudiées ») avec l’appartenance départementale et la catégorie de ZAU.
load("data/refdata_abst.Rdata")
labels_COM_NOUV <- c("Communes inchangées", "Communes nouvelles")
couleurs <- c("#2b83ba", "red4")
colnames(df_new_abst)
## [1] "CODGEO_new" "LIBGEO_new" "CODE_DEPT_new" "CATAEU2010"
## [5] "COM_NOUV" "FusDate" "LIBSUBCOM_2020" "NBRINS_2020"
## [9] "NBRABS_2020" "NBREXP_2020" "PCTVOTINS_2020" "PCTABSINS_2020"
## [13] "PCTEXPINS_2020" "type_comm_2020" "CODGEO" "LIBGEO"
## [17] "CODE_DEPT" "CATAEU2010_2014" "COM_NOUV_2014" "FusDate_2014"
## [21] "LIBSUBCOM_2014" "NBRINS_2014" "NBRABS_2014" "NBREXP_2014"
## [25] "PCTVOTINS_2014" "PCTABSINS_2014" "PCTEXPINS_2014"
df_new_abst$PCTVOTINS_evol <- round((df_new_abst$PCTVOTINS_2020 - df_new_abst$PCTVOTINS_2014) / df_new_abst$PCTVOTINS_2014, 2)
df_new_abst$PCTVOTINS_evol_brute <- df_new_abst$PCTVOTINS_2020 - df_new_abst$PCTVOTINS_2014
df_new_abst$PCTABSINS_evol_brute <-df_new_abst$PCTABSINS_2020 - df_new_abst$PCTABSINS_2014
df_new_abst$PCTABSINS_evol <- round((df_new_abst$PCTABSINS_2020 - df_new_abst$PCTABSINS_2014) / df_new_abst$PCTABSINS_2014, 2)
df_new_abst$PCTEXPINS_evol <- round((df_new_abst$PCTEXPINS_2020 - df_new_abst$PCTEXPINS_2014) / df_new_abst$PCTEXPINS_2014, 2)
df_new_abst$PCTEXPINS_evol_brute <- df_new_abst$PCTEXPINS_2020 - df_new_abst$PCTEXPINS_2014
variables_evolutions <- c("PCTVOTINS_evol", "PCTVOTINS_evol_brute", "PCTABSINS_evol", "PCTABSINS_evol_brute", "PCTEXPINS_evol", "PCTEXPINS_evol_brute")
noms_variables <- c("Évolution du pourcentage de votants par rapport\nau nombre d'inscrits entre 2014 et 2020 (%)",
"Évolution du pourcentage de votants par rapport\nau nombre d'inscrits entre 2014 et 2020",
"Évolution du pourcentage d'abstentionnistes par rapport\nau nombre d'inscrits entre 2014 et 2020 (%)",
"Évolution du pourcentage d'abstentionnistes par rapport\nau nombre d'inscrits entre 2014 et 2020",
"Évolution du pourcentage de votes exprimés par rapport\nau nombre d'inscrits entre 2014 et 2020 (%)",
"Évolution du pourcentage de votes exprimés par rapport\nau nombre d'inscrits entre 2014 et 2020")
variable <- variables_evolutions[1]
# Nombre pas négligeables de NA, mais non pris en compte dans les boxplots, donc cela ne change pas l'analyse et les communes nouvelles sont présentes à peu près dans les mêmes proportions que dans le reste des communes.
summary(is.na(df_new_abst$NBRINS_2020))
## Mode FALSE TRUE
## logical 31203 3176
# df_new_abst2 <- df_new_abst %>% filter(!is.na(NBRINS_2020))
df_new_abst_NA <- subset (df_new_abst, is.na (df_new_abst$NBRINS_2020))
table (df_new_abst_NA$COM_NOUV)
##
## NON OUI
## 3008 168
for (variable in variables_evolutions) {
nom_variable <- noms_variables[which(variables_evolutions == variable)]
boxplot <- ggplot(df_new_abst, aes(x = COM_NOUV, y = df_new_abst[, variable], fill = COM_NOUV, color = COM_NOUV)) +
geom_boxplot(width = 1.5, varwidth = TRUE) +
scale_color_manual(values=couleurs , labels = labels_COM_NOUV) +
scale_fill_manual(values = c("white", "white", "white"), labels = labels_COM_NOUV) +
labs(fill = " ", color = " ") +
ylab(nom_variable) +
xlab("Statut de la commune") +
ggtitle(paste0(nom_variable, "\nen fonction du statut communal"))+
# coord_cartesian(ylim=c(lower.limit, upper.limit)) +
theme(axis.text.x = element_text(angle = 45, hjust = 1, size = 10), legend.position = "right")
print (boxplot)
print(paste0("Éléments statistiques de la variable : " , nom_variable))
print(summary(df_new_abst[, variable]))
print(paste0("Éléments statistiques de la variable : " , nom_variable, " en croisant avec le statut de commune nouvelle ou non"))
print(tapply(df_new_abst[, variable], df_new_abst$COM_NOUV, summary))
# En discrétisant par ZAU
df_new_abst_ZAU <- subset(df_new_abst, nchar(df_new_abst$CATAEU2010) == 3)
boxplot <- ggplot(df_new_abst_ZAU, aes(x = CATAEU2010, y = df_new_abst_ZAU[, variable], color = COM_NOUV)) +
geom_boxplot(varwidth = TRUE, width = 1.5) +
scale_color_manual(values=couleurs , labels = labels_COM_NOUV) +
scale_fill_manual(values = c("white", "white", "white"), labels = labels_COM_NOUV) +
labs(fill = " ", color = " ") +
ylab(nom_variable) +
xlab("Statut de la commune dans le ZAU") +
# scale_x_discrete(labels = nom_strates) +
ggtitle(paste0(nom_variable, "\nen discrétisant par ZAU")) +
theme(axis.text.x = element_text(angle = 70, hjust = 1))
print (boxplot)
# En discrétisant par régions, pour faire une première vérification de l'effet de contexte
# Nécessaire d'importer données d'appartenance pour avoir la région au 1er janvier 2025
appartenance_2025 <- data.frame(read_excel("data-raw/stats_insee/table-appartenance-geo-communes-2025.xlsx", sheet = "COM", skip = 5))
# colnames(appartenance_2025)
df_new_abst_REG <- merge(df_new_abst, appartenance_2025, by.x = "CODGEO_new", by.y = "CODGEO", suffixes = c("", "_2025"))
# colnames(df_new_abst_REG)
boxplot <- ggplot(df_new_abst_REG, aes(x = REG, y = df_new_abst_REG[, variable], color = COM_NOUV)) +
geom_boxplot(varwidth = TRUE, width = 1.5) +
# coord_cartesian(ylim=c(lower.limit, upper.limit)) +
scale_color_manual(values=couleurs , labels = labels_COM_NOUV) +
scale_fill_manual(values = c("white", "white", "white"), labels = labels_COM_NOUV) +
labs(fill = " ", color = " ") + ylab(nom_variable) +
xlab("Région") +
# scale_x_discrete(labels = nom_strates) +
ggtitle(paste0(nom_variable, "\nen discrétisant par région (2025)")) +
theme(axis.text.x = element_text(angle = 70, hjust = 1))
print(boxplot)
# On modifie éventuellement le graphique pour le rendre plus lisible si valeurs extrêmes
# upper.limit <- quantile(df_new_abst[, variable], na.rm = TRUE)[4] + 4*IQR(df_new_abst[, variable], na.rm = TRUE)
# lower.limit <- quantile(df_new_abst[, variable], na.rm = TRUE)[2] - 4*IQR(df_new_abst[, variable], na.rm = TRUE)
# print (boxplot + coord_cartesian(ylim=c(lower.limit, upper.limit)))
# print (boxplot + coord_cartesian(ylim=c(, upper.limit)))
}
## [1] "Éléments statistiques de la variable : Évolution du pourcentage de votants par rapport\nau nombre d'inscrits entre 2014 et 2020 (%)"
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -0.770 -0.300 -0.200 -0.199 -0.100 0.750 4246
## [1] "Éléments statistiques de la variable : Évolution du pourcentage de votants par rapport\nau nombre d'inscrits entre 2014 et 2020 (%) en croisant avec le statut de commune nouvelle ou non"
## $NON
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -0.770 -0.300 -0.200 -0.197 -0.100 0.750 4036
##
## $OUI
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -0.6300 -0.3900 -0.2900 -0.2852 -0.1800 0.2000 210
## [1] "Éléments statistiques de la variable : Évolution du pourcentage de votants par rapport\nau nombre d'inscrits entre 2014 et 2020"
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -61.21 -21.96 -15.21 -14.78 -7.70 42.86 4246
## [1] "Éléments statistiques de la variable : Évolution du pourcentage de votants par rapport\nau nombre d'inscrits entre 2014 et 2020 en croisant avec le statut de commune nouvelle ou non"
## $NON
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -61.21 -21.80 -15.11 -14.66 -7.56 42.86 4036
##
## $OUI
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -45.81 -27.74 -20.80 -20.39 -13.20 13.58 210
## [1] "Éléments statistiques de la variable : Évolution du pourcentage d'abstentionnistes par rapport\nau nombre d'inscrits entre 2014 et 2020 (%)"
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -1.00 0.32 0.60 Inf 0.98 Inf 4251
## [1] "Éléments statistiques de la variable : Évolution du pourcentage d'abstentionnistes par rapport\nau nombre d'inscrits entre 2014 et 2020 (%) en croisant avec le statut de commune nouvelle ou non"
## $NON
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -1.00 0.31 0.60 Inf 0.98 Inf 4041
##
## $OUI
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -0.6100 0.4800 0.7600 0.8172 1.0700 12.5500 210
## [1] "Éléments statistiques de la variable : Évolution du pourcentage d'abstentionnistes par rapport\nau nombre d'inscrits entre 2014 et 2020"
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -42.86 7.70 15.21 14.78 21.96 61.21 4246
## [1] "Éléments statistiques de la variable : Évolution du pourcentage d'abstentionnistes par rapport\nau nombre d'inscrits entre 2014 et 2020 en croisant avec le statut de commune nouvelle ou non"
## $NON
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -42.86 7.56 15.11 14.66 21.80 61.21 4036
##
## $OUI
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -13.58 13.20 20.80 20.39 27.74 45.81 210
## [1] "Éléments statistiques de la variable : Évolution du pourcentage de votes exprimés par rapport\nau nombre d'inscrits entre 2014 et 2020 (%)"
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -0.930 -0.300 -0.190 -0.187 -0.090 1.500 4246
## [1] "Éléments statistiques de la variable : Évolution du pourcentage de votes exprimés par rapport\nau nombre d'inscrits entre 2014 et 2020 (%) en croisant avec le statut de commune nouvelle ou non"
## $NON
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -0.930 -0.290 -0.190 -0.185 -0.090 1.500 4036
##
## $OUI
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -0.7600 -0.4300 -0.2800 -0.2886 -0.1600 0.6100 210
## [1] "Éléments statistiques de la variable : Évolution du pourcentage de votes exprimés par rapport\nau nombre d'inscrits entre 2014 et 2020"
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -68.62 -20.47 -13.89 -13.54 -6.48 46.69 4246
## [1] "Éléments statistiques de la variable : Évolution du pourcentage de votes exprimés par rapport\nau nombre d'inscrits entre 2014 et 2020 en croisant avec le statut de commune nouvelle ou non"
## $NON
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -68.62 -20.35 -13.79 -13.40 -6.39 46.69 4036
##
## $OUI
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -52.89 -26.88 -18.53 -19.54 -11.75 21.02 210
On observe une abstention en recul, ce qui s’explique par le contexte de la pandémie. Mais on observe aussi que ce recul est bien plus net pour les communes nouvelles.
On s’intéresse aux communes de moins de 1000 habitants, puisque leur mode de scrutin est différent (et que certaines communes nouvelles ont pu avoir davantage de mal que d’autres communes à constituer plusieurs listes aux élections de 2020, ce qui expliquerait en partie l’abstention plus forte).
load("data/refdata_abst.Rdata")
labels_COM_NOUV <- c("Communes inchangées", "Communes nouvelles")
couleurs <- c("#2b83ba", "red4")
colnames(df_new_abst)
## [1] "CODGEO_new" "LIBGEO_new" "CODE_DEPT_new" "CATAEU2010"
## [5] "COM_NOUV" "FusDate" "LIBSUBCOM_2020" "NBRINS_2020"
## [9] "NBRABS_2020" "NBREXP_2020" "PCTVOTINS_2020" "PCTABSINS_2020"
## [13] "PCTEXPINS_2020" "type_comm_2020" "CODGEO" "LIBGEO"
## [17] "CODE_DEPT" "CATAEU2010_2014" "COM_NOUV_2014" "FusDate_2014"
## [21] "LIBSUBCOM_2014" "NBRINS_2014" "NBRABS_2014" "NBREXP_2014"
## [25] "PCTVOTINS_2014" "PCTABSINS_2014" "PCTEXPINS_2014"
df_new_abst$PCTVOTINS_evol <- round((df_new_abst$PCTVOTINS_2020 - df_new_abst$PCTVOTINS_2014) / df_new_abst$PCTVOTINS_2014, 2)
df_new_abst$PCTVOTINS_evol_brute <- df_new_abst$PCTVOTINS_2020 - df_new_abst$PCTVOTINS_2014
df_new_abst$PCTABSINS_evol_brute <-df_new_abst$PCTABSINS_2020 - df_new_abst$PCTABSINS_2014
df_new_abst$PCTABSINS_evol <- round((df_new_abst$PCTABSINS_2020 - df_new_abst$PCTABSINS_2014) / df_new_abst$PCTABSINS_2014, 2)
df_new_abst$PCTEXPINS_evol <- round((df_new_abst$PCTEXPINS_2020 - df_new_abst$PCTEXPINS_2014) / df_new_abst$PCTEXPINS_2014, 2)
df_new_abst$PCTEXPINS_evol_brute <- df_new_abst$PCTEXPINS_2020 - df_new_abst$PCTEXPINS_2014
variables_evolutions <- c("PCTVOTINS_evol", "PCTVOTINS_evol_brute", "PCTABSINS_evol", "PCTABSINS_evol_brute", "PCTEXPINS_evol", "PCTEXPINS_evol_brute")
noms_variables <- c("Évolution du pourcentage de votants par rapport\nau nombre d'inscrits entre 2014 et 2020 (%)",
"Évolution du pourcentage de votants par rapport\nau nombre d'inscrits entre 2014 et 2020",
"Évolution du pourcentage d'abstentionnistes par rapport\nau nombre d'inscrits entre 2014 et 2020 (%)",
"Évolution du pourcentage d'abstentionnistes par rapport\nau nombre d'inscrits entre 2014 et 2020",
"Évolution du pourcentage de votes exprimés par rapport\nau nombre d'inscrits entre 2014 et 2020 (%)",
"Évolution du pourcentage de votes exprimés par rapport\nau nombre d'inscrits entre 2014 et 2020")
variable <- variables_evolutions[1]
# On ne sélectionne que les communes identifiées comme ayant moins de 1000 habitants
df_new_abst_moins1000 <- subset (df_new_abst, df_new_abst$type_comm_2020 == "moins_1000")
for (variable in variables_evolutions) {
nom_variable <- noms_variables[which(variables_evolutions == variable)]
boxplot <- ggplot(df_new_abst_moins1000, aes(x = COM_NOUV, y = df_new_abst_moins1000[, variable], fill = COM_NOUV, color = COM_NOUV)) +
geom_boxplot(width = 1.5, varwidth = TRUE) +
scale_color_manual(values=couleurs , labels = labels_COM_NOUV) +
scale_fill_manual(values = c("white", "white", "white"), labels = labels_COM_NOUV) +
labs(fill = " ", color = " ") +
ylab(nom_variable) +
xlab("Statut de la commune") +
ggtitle(paste0(nom_variable, "\nen fonction du statut communal"))+
# coord_cartesian(ylim=c(lower.limit, upper.limit)) +
theme(axis.text.x = element_text(angle = 45, hjust = 1, size = 10), legend.position = "right")
print (boxplot)
print(paste0("Éléments statistiques de la variable : " , nom_variable))
print(summary(df_new_abst_moins1000[, variable]))
print(paste0("Éléments statistiques de la variable : " , nom_variable, " en croisant avec le statut de commune nouvelle ou non"))
print(tapply(df_new_abst_moins1000[, variable], df_new_abst_moins1000$COM_NOUV, summary))
# En discrétisant par ZAU
df_new_abst_ZAU <- subset(df_new_abst_moins1000, nchar(df_new_abst_moins1000$CATAEU2010) == 3)
boxplot <- ggplot(df_new_abst_ZAU, aes(x = CATAEU2010, y = df_new_abst_ZAU[, variable], color = COM_NOUV)) +
geom_boxplot(varwidth = TRUE, width = 1.5) +
scale_color_manual(values=couleurs , labels = labels_COM_NOUV) +
scale_fill_manual(values = c("white", "white", "white"), labels = labels_COM_NOUV) +
labs(fill = " ", color = " ") +
ylab(nom_variable) +
xlab("Statut de la commune dans le ZAU") +
# scale_x_discrete(labels = nom_strates) +
ggtitle(paste0(nom_variable, "\nen discrétisant par ZAU")) +
theme(axis.text.x = element_text(angle = 70, hjust = 1))
print (boxplot)
# En discrétisant par régions, pour faire une première vérification de l'effet de contexte
# Nécessaire d'importer données d'appartenance pour avoir la région au 1er janvier 2025
appartenance_2025 <- data.frame(read_excel("data-raw/stats_insee/table-appartenance-geo-communes-2025.xlsx", sheet = "COM", skip = 5))
# colnames(appartenance_2025)
df_new_abst_REG <- merge(df_new_abst_moins1000, appartenance_2025, by.x = "CODGEO_new", by.y = "CODGEO", suffixes = c("", "_2025"))
# colnames(df_new_abst_REG)
boxplot <- ggplot(df_new_abst_REG, aes(x = REG, y = df_new_abst_REG[, variable], color = COM_NOUV)) +
geom_boxplot(varwidth = TRUE, width = 1.5) +
# coord_cartesian(ylim=c(lower.limit, upper.limit)) +
scale_color_manual(values=couleurs , labels = labels_COM_NOUV) +
scale_fill_manual(values = c("white", "white", "white"), labels = labels_COM_NOUV) +
labs(fill = " ", color = " ") + ylab(nom_variable) +
xlab("Région") +
# scale_x_discrete(labels = nom_strates) +
ggtitle(paste0(nom_variable, "\nen discrétisant par région (2025)")) +
theme(axis.text.x = element_text(angle = 70, hjust = 1))
print(boxplot)
# On modifie éventuellement le graphique pour le rendre plus lisible si valeurs extrêmes
# upper.limit <- quantile(df_new_abst[, variable], na.rm = TRUE)[4] + 4*IQR(df_new_abst[, variable], na.rm = TRUE)
# lower.limit <- quantile(df_new_abst[, variable], na.rm = TRUE)[2] - 4*IQR(df_new_abst[, variable], na.rm = TRUE)
# print (boxplot + coord_cartesian(ylim=c(lower.limit, upper.limit)))
# print (boxplot + coord_cartesian(ylim=c(, upper.limit)))
}
## [1] "Éléments statistiques de la variable : Évolution du pourcentage de votants par rapport\nau nombre d'inscrits entre 2014 et 2020 (%)"
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -0.7700 -0.2700 -0.1800 -0.1728 -0.0800 0.7500 213
## [1] "Éléments statistiques de la variable : Évolution du pourcentage de votants par rapport\nau nombre d'inscrits entre 2014 et 2020 (%) en croisant avec le statut de commune nouvelle ou non"
## $NON
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -0.7700 -0.2700 -0.1800 -0.1724 -0.0800 0.7500 205
##
## $OUI
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -0.5200 -0.3000 -0.2200 -0.2086 -0.1300 0.2000 8
## [1] "Éléments statistiques de la variable : Évolution du pourcentage de votants par rapport\nau nombre d'inscrits entre 2014 et 2020"
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -61.21 -20.69 -13.81 -13.39 -6.48 42.86 213
## [1] "Éléments statistiques de la variable : Évolution du pourcentage de votants par rapport\nau nombre d'inscrits entre 2014 et 2020 en croisant avec le statut de commune nouvelle ou non"
## $NON
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -61.21 -20.66 -13.79 -13.36 -6.44 42.86 205
##
## $OUI
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -43.54 -22.85 -17.11 -15.99 -10.19 13.58 8
## [1] "Éléments statistiques de la variable : Évolution du pourcentage d'abstentionnistes par rapport\nau nombre d'inscrits entre 2014 et 2020 (%)"
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -1.00 0.28 0.60 Inf 1.01 Inf 218
## [1] "Éléments statistiques de la variable : Évolution du pourcentage d'abstentionnistes par rapport\nau nombre d'inscrits entre 2014 et 2020 (%) en croisant avec le statut de commune nouvelle ou non"
## $NON
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -1.00 0.28 0.60 Inf 1.01 Inf 210
##
## $OUI
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -0.610 0.440 0.695 0.809 1.022 12.550 8
## [1] "Éléments statistiques de la variable : Évolution du pourcentage d'abstentionnistes par rapport\nau nombre d'inscrits entre 2014 et 2020"
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -42.86 6.48 13.81 13.39 20.69 61.21 213
## [1] "Éléments statistiques de la variable : Évolution du pourcentage d'abstentionnistes par rapport\nau nombre d'inscrits entre 2014 et 2020 en croisant avec le statut de commune nouvelle ou non"
## $NON
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -42.86 6.44 13.79 13.36 20.66 61.21 205
##
## $OUI
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -13.58 10.19 17.11 15.99 22.85 43.54 8
## [1] "Éléments statistiques de la variable : Évolution du pourcentage de votes exprimés par rapport\nau nombre d'inscrits entre 2014 et 2020 (%)"
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -0.9300 -0.2700 -0.1700 -0.1656 -0.0700 1.0800 213
## [1] "Éléments statistiques de la variable : Évolution du pourcentage de votes exprimés par rapport\nau nombre d'inscrits entre 2014 et 2020 (%) en croisant avec le statut de commune nouvelle ou non"
## $NON
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -0.9300 -0.2700 -0.1700 -0.1652 -0.0700 1.0800 205
##
## $OUI
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -0.5400 -0.3000 -0.2200 -0.2052 -0.1200 0.2200 8
## [1] "Éléments statistiques de la variable : Évolution du pourcentage de votes exprimés par rapport\nau nombre d'inscrits entre 2014 et 2020"
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -68.62 -19.75 -12.88 -12.50 -5.59 46.69 213
## [1] "Éléments statistiques de la variable : Évolution du pourcentage de votes exprimés par rapport\nau nombre d'inscrits entre 2014 et 2020 en croisant avec le statut de commune nouvelle ou non"
## $NON
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -68.62 -19.72 -12.85 -12.47 -5.55 46.69 205
##
## $OUI
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -44.26 -22.16 -15.88 -15.25 -9.31 14.43 8
Pour les élections avant les fusions : Quelle proximité politique (ou non) des communes fusionnantes au sein d’une même commune nouvelle. Cf. section “Chaque CN est-elle composée d’un seul type” ?
On réalise une ACP en fonction des données électorales sur l’ensemble des communes françaises. À partir de là, on regarde comment se positionnent les communes nouvelles au sein de ces catégories.
Choix des élections de 2012 car avant le mouvement des fusions et des élections de 2022 car après le mouvement des fusions.
# Import des données sur les élections de 2012 doit avoir été fait plus haut
colnames(PR2012_T1) <- paste0("PR2012_T1_", colnames(PR2012_T1))
colnames(PR2012_T2) <- paste0("PR2012_T2_", colnames(PR2012_T2))
colnames(PR2022_T1) <- paste0("PR2022_T1_", colnames(PR2022_T1))
colnames(PR2022_T2) <- paste0("PR2022_T2_", colnames(PR2022_T2))
colnames(df2011_PR2017_T1)[14:ncol(df2011_PR2017_T1)] <- paste0("PR2017_T1_", colnames(df2011_PR2017_T1)[14:ncol(df2011_PR2017_T1)])
colnames(df2011_PR2017_T2)[14:ncol(df2011_PR2017_T2)] <- paste0("PR2017_T2_", colnames(df2011_PR2017_T2)[14:ncol(df2011_PR2017_T2)])
colnames(df2011_PR2022_T1)[14:ncol(df2011_PR2022_T1)] <- paste0("PR2022_T1_", colnames(df2011_PR2022_T1)[14:ncol(df2011_PR2022_T1)])
df2011_elect <- merge(df2011, PR2012_T1, by.x = "CODGEO", by.y = "PR2012_T1_CODGEO", all.x = TRUE)
df2011_elect <- merge(df2011_elect, PR2012_T2, by.x = "CODGEO", by.y = "PR2012_T2_CODGEO", all.x = TRUE)
df_new_elect <- merge(df_new, PR2022_T1, by.x = "CODGEO_new", by.y = "PR2022_T1_CODGEO", all.x = TRUE)
df_new_elect <- merge(df_new_elect, PR2022_T2, by.x = "CODGEO_new", by.y = "PR2022_T2_CODGEO", all.x = TRUE)
datafus2011 <- subset(df2011_elect, COM_NOUV == "OUI") # Désigne les données concernant les communes ayant participé à la création d'une commune nouvelle, appelées ici communes fusionnantes
# Calcul de la surface si besoin
# datafus2011$surface <- st_area(geomfus2011) # Attention, unités : m²
# datafus2011$surface <- set_units(datafus2011$surface, km^2) # On passe en km²
# Appariement des données
geomfus2011 <- merge(geomfus2011, datafus2011, by = "CODGEO")
geom2011 <- merge(geom2011, df2011, by = "CODGEO")
geom_new <- merge(geom_new, df_new, by = "CODGEO_new")
# Import données pour les noms de variables
# ratio <- as.data.frame(read_excel("data-raw/meta.xlsx", sheet = "ratios"))
# row.names(ratio) <- ratio$Numerator_Code
# ÉTAPE 1/3 : CHOIX DES DONNÉE ET DE L'ÉLECTION
# Pour données élections 2012
# PourCAH_ttes_var <- df2011_elect
# elect <- "PR2012_T1"
# Pour données élections 2017
PourCAH_ttes_var <- df2011_PR2017_T1
elect <- "PR2017_T1"
# Pour données élections 2022 (NB : choix des données 2011 qui permettent d'avoir les communes fusionnantes ou données df_new avec que les communes nouvelles)
# PourCAH_ttes_var <- df2011_PR2022_T1
# PourCAH_ttes_var <- df_new_elect
# elect <- "PR2022_T1"
Code_pour_row_names <- "CODGEO" # Pour 2012 et 2017 et 2022 si utilisation données df_2011
# Code_pour_row_names <- "CODGEO_new" # Pour 2022 si utilisation données df_new
# ÉTAPE 2/3 : CHOIX DU PÉRIMÈTRE
espace <- "France"
# Pour ne prendre qu'une partie des communes françaises
# PourCAH_ttes_var <- subset (PourCAH_ttes_var, REG == "23" | REG == "25"| REG == "53"| REG == "52") # Normandies, Bretagne, Pays-de-la-Loire
# espace <- "Ouest"
# PourCAH_ttes_var <- subset(PourCAH_ttes_var, REG == "23" | REG == "25") # Haute et Basse Normandie
# espace <- "Normandie"
# PourCAH_ttes_var <- subset (PourCAH_ttes_var, CODE_DEPT == "69" | CODE_DEPT == "73" | CODE_DEPT == "74" | CODE_DEPT == "38" | CODE_DEPT == "01") # Rhône-Alpes partiel
# espace <- "RALP_partiel"
# PourCAH_ttes_var <- subset (PourCAH_ttes_var, CODE_DEPT == "49" ) # Département du Maine-et-Loire
# PourCAH_ttes_var <- subset (PourCAH_ttes_var, CODE_DEPT_new == "49" ) # Département du Maine-et-Loire
# espace <- "Maine-et-Loire"
# ÉTAPE 3/3 : CHOIX DES VARIABLES
# Sélection de variables sur les deux tours de l'élection présidentielle de 2012
# selecVar <- c("CODGEO", "COM_NOUV", "CODE_DEPT", "REG", "CATAEU2010", "CODGEO_new", "LIBGEO_new",
# "PR2012_T1_Abst_prct_insc", "PR2012_T1_BlcsNuls_prct_vote",
# "PR2012_T1_prct_insc_LE.PEN", "PR2012_T1_prct_insc_SARKOZY", "PR2012_T1_prct_insc_MÉLENCHON", "PR2012_T1_prct_insc", "PR2012_T1_prct_insc_HOLLANDE",
# "PR2012_T2_Abst_prct_insc", "PR2012_T2_BlcsNuls_prct_vote", "PR2012_T2_prct_insc_HOLLANDE", "PR2012_T2_prct_insc_SARKOZY")
# Sélection de variables uniquement sur le premier tour pour l'élection présidentielle de 2012
# selecVar <- c("CODGEO", "COM_NOUV", "CODE_DEPT", "REG", "CATAEU2010", "CODGEO_new", "LIBGEO_new",
# "PR2012_T1_Abst_prct_insc", "PR2012_T1_BlcsNuls_prct_insc",
# "PR2012_T1_prct_insc_LE.PEN", "PR2012_T1_prct_insc_SARKOZY", "PR2012_T1_prct_insc_MÉLENCHON", "PR2012_T1_prct_insc_BAYROU", "PR2012_T1_prct_insc_HOLLANDE")
# Sélection de variables uniquement sur le premier tour pour l'élection présidentielle de 2012 sans bulletins blancs et nuls
# selecVar <- c("CODGEO", "COM_NOUV", "CODE_DEPT", "REG", "CATAEU2010", "CODGEO_new", "LIBGEO_new",
# "PR2012_T1_Abst_prct_insc", "PR2012_T1_prct_insc_LE.PEN", "PR2012_T1_prct_insc_SARKOZY", "PR2012_T1_prct_insc_MÉLENCHON", "PR2012_T1_prct_insc_BAYROU", "PR2012_T1_prct_insc_HOLLANDE")
# Sélection de variables uniquement sur le premier tour pour l'élection présidentielle de 2017 sans bulletins blancs et nuls
selecVar <- c("CODGEO", "COM_NOUV", "CODE_DEPT", "REG", "CATAEU2010", "CODGEO_new", "LIBGEO_new",
"PR2017_T1_Abst_prct_insc", "PR2017_T1_prct_insc_LE.PEN", "PR2017_T1_prct_insc_FILLON", "PR2017_T1_prct_insc_MÉLENCHON", "PR2017_T1_prct_insc_MACRON", "PR2017_T1_prct_insc_HAMON")
# Sélection de variables uniquement sur le premier tour pour l'élection présidentielle de 2022
# selecVar <- c("CODGEO", "COM_NOUV", "CODE_DEPT_new", "REG", "CATAEU2010", "CODGEO_new", "LIBGEO_new",
# "PR2022_T1_Abst_prct_insc", "PR2022_T1_Blancs_prct_insc",
# "PR2022_T1_prct_insc_LE.PEN", "PR2022_T1_prct_insc_MACRON", "PR2022_T1_prct_insc_MÉLENCHON")
# Sélection de variables uniquement sur le premier tour pour l'élection présidentielle de 2022 sans bulletins blancs
# selecVar <- c("CODGEO", "COM_NOUV", "CODE_DEPT", "REG", "CATAEU2010", "CODGEO_new", "LIBGEO_new",
# "PR2022_T1_Abst_prct_insc", "PR2022_T1_prct_insc_LE.PEN", "PR2022_T1_prct_insc_MACRON", "PR2022_T1_prct_insc_MÉLENCHON", "PR2022_T1_prct_insc_ZEMMOUR")
PourCAH <- PourCAH_ttes_var[,selecVar]
setdiff(PourCAH_ttes_var$LIBGEO_new, PourCAH$LIBGEO_new)
## character(0)
PourCAH <- na.omit(PourCAH)
# row.names(PourCAH) <- PourCAH$CODGEO # Pour 2012 et 2017 et 2022 si utilisation données df_2011
# row.names(PourCAH) <- PourCAH$CODGEO_new # Pour 2022
row.names(PourCAH) <- PourCAH[, Code_pour_row_names]
PourCAH$CODGEO <- NULL
PourCAH$CODE_DEPT <- NULL
PourCAH$COM_NOUV <- NULL
PourCAH$CATAEU2010 <- NULL
PourCAH$CODGEO_new <- NULL
PourCAH$CODE_DEPT_new <- NULL
PourCAH$LIBGEO_new <- NULL
PourCAH$REG <- NULL
NbrVariables <- ncol(PourCAH)
# Pour rattraper une erreur au départ
# PourCAH$PR2012_T1_BlcsNuls_prct_expr[PourCAH$PR2012_T1_BlcsNuls_prct_expr == Inf] <- 100
# PourCAH$PR2012_T2_BlcsNuls_prct_expr[PourCAH$PR2012_T2_BlcsNuls_prct_expr == Inf] <- 100
selecVarCAH <- colnames(PourCAH)
res.pca <- PCA(PourCAH, graph = FALSE)
#res.pca <- PCA(PourCAH, ncp = 5, graph = FALSE) # 50 % of cumulative variance
# res.hcpc <- HCPC(res.pca, graph = TRUE, method = "ward", metric = "euclidian") #Ici coupure à 8 classes pas trop mal
#res.hcpc <- HCPC(res.pca, graph = FALSE, nb.clust = 7, method = "ward", metric = "euclidian") #Pour faire la coupure de manière déterministe
res.hcpc <- agnes(res.pca$ind$coord, metric = "euclidiean", method = "ward")
# Réalisation du dendrogramme en passant par plot
dendro.hcpc <- as.dendrogram(res.hcpc)
plot(dendro.hcpc, leaflab = "none", ylab = "Dissimilarité")
inertie <- sort(res.hcpc$height, decreasing = TRUE)
plot(inertie[1:20], type = "s", xlab = "Nombre de classes", ylab = "Inertie")
# Affichage de différents graphiques pour aider au découpage
sortedHeight <- sort(res.hcpc$height^2, decreasing = TRUE)
plot(sortedHeight,
type = "h",
xlab = "Noeuds",
ylab = "Niveau d'agrégation")
relHeight <- sortedHeight / sum(sortedHeight) * 100
cumHeight <- cumsum(relHeight)
barplot(relHeight[1:30], names.arg = seq(1, 30, 1),
col = "black", border = "white", xlab = "Noeuds",
ylab = "Part de l'inertie totale (%)",
main = "Diagramme de niveaux")
# Coupure de l'arbre (k = nombre de classes)
nclass <- 5
cluspop <- cutree(res.hcpc, k = nclass)
# cluspop
# couleurs <- c("#e41a1c","#377eb8","#4daf4a","#984ea3") # Pour 4
# couleurs <- c("#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00") # Pour 5
couleurs <- c("#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628","#f781bf") # Pour 8
NB : On garde l’appellation ‘PourCAH’ dans l’objectif de simplifier le code mais il faut être attentif à vérifier si les données sont issues d’une CAH ou d’un k-means.
Ressources pour la mise en œuvre : https://delladata.fr/kmeans/ et https://uc-r.github.io/kmeans_clustering.
df <- scale(PourCAH) # Standardisation des données
k2 <- kmeans(df, centers = 2, nstart = 25)
k3 <- kmeans(df, centers = 3, nstart = 25)
k4 <- kmeans(df, centers = 4, nstart = 25)
k5 <- kmeans(df, centers = 5, nstart = 25)
# plots to compare
p1 <- fviz_cluster(k2, geom = "point", data = df) + ggtitle("k = 2")
p2 <- fviz_cluster(k3, geom = "point", data = df) + ggtitle("k = 3")
p3 <- fviz_cluster(k4, geom = "point", data = df) + ggtitle("k = 4")
p4 <- fviz_cluster(k5, geom = "point", data = df) + ggtitle("k = 5")
# library(gridExtra)
gridExtra::grid.arrange(p1, p2, p3, p4, nrow = 2)
# Trop lourd à jouer
# Représentations graphiques du nombre de clusters
# Elbow method
fviz_nbclust(df, kmeans, method = "wss", k.max = 5) +
labs(subtitle = "Elbow method")
# Silhouette method
fviz_nbclust(df, kmeans, method = "silhouette", k.max = 5) +
labs(subtitle = "Silhouette method")
# Gap statistic
# nboot = 50 to keep the function speedy.
# recommended value: nboot= 500 for your analysis.
# Use verbose = FALSE to hide computing progression.
set.seed(123)
nbrtests <- 50
fviz_nbclust(df, kmeans, nstart = 25, method = "gap_stat", nboot = nbrtests, k.max = 5) +
labs(subtitle = paste("Gap statistic method. Nbr tests :", nbrtests))
rm(df, k2, k3, k4, k5, p1, p2, p3, p4, nbrtests)
PourCAH_scale <- scale(PourCAH) # Standardisation des données
# Définition du nombre de cluster/classes
nclass <- 5
couleurs <- c("#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628","#f781bf") # Pour 8
kmeans_out <- kmeans(PourCAH_scale, centers = nclass, nstart = 25)
# kmeans_out
fviz_cluster(kmeans_out, data = PourCAH)
# Pour visualiser la relation entre les clasters et chacune des variables
pairs(PourCAH, col=c(1:nclass)[kmeans_out$cluster])
# Pour faciliter la suite du code, on reprend la même terminaison que la CAH
cluspop <- kmeans_out$cluster
# Définition de noms de groupes
# Noms pour typo avec les navetteurs, avec 5 classes
# NB : NOMS ADAPTÉS POUR LES DONNÉES 2011-2020 UNIQUEMENT
# NomsGroupesCAH <- c("Groupe 1 PPCQ", # Proche Périphérie, Cadres, Quinquagénaires
# "Groupe 2 PFO", # Périphéries Familiales et Ouvrières
# "Groupe 3 MOARO", # Moyen, Ouvriers, Agriculteurs, Retraités, Out.
# "Groupe 4 VAR", # Vieillissantes, Agricoles et Rurales
# "Groupe 5 REAV" # Rurales, Enclavées, Agricoles et Vieillissantes
# )
# Si on ne veut pas définir de noms
NomsGroupesCAH <- paste ("Groupe", 1:nclass)
# On intègre ces données dans le tableau de départ
PourCAH <- as.data.frame(PourCAH, stringsAsFactors = FALSE)
PourCAH$Groupes <- factor(cluspop,
levels = 1:nclass,
labels = paste(NomsGroupesCAH))
# On identifie le nombre de chaque groupe
Groupes_nbr <- paste0(NomsGroupesCAH, " (n=", table(PourCAH$Groupes), ")")
names(Groupes_nbr) <- NomsGroupesCAH
PourCAH$CODGEO <- row.names(PourCAH)
# Calcul de la moyenne des variables
clusProfile <- aggregate(PourCAH [, 1:NbrVariables],
by = list(PourCAH$Groupes),
mean)
colnames(clusProfile)[1] <- "Groupes"
clusLong <- melt(clusProfile, id.vars = "Groupes")
ggplot(clusLong) +
geom_bar(aes(x = variable, y = value, fill = Groupes),
stat = "identity") +
scale_fill_manual(values=couleurs) +
facet_wrap(~ Groupes, labeller = labeller(Groupes = Groupes_nbr)) +
coord_flip() +
theme_bw()
# Calculs des valeurs moyennes (pour comparaison)
# On identifie les variables en stock
VarCAHBrutes <- stringr::str_replace(selecVarCAH, "prct_insc", "nbre_voix")
# Quelques cas particuliers
VarCAHBrutes <- stringr::str_replace(VarCAHBrutes, "Abst_nbre_voix", "Abst_nbre")
VarCAHBrutes <- stringr::str_replace(VarCAHBrutes, "BlcsNuls_nbre_voix", "BlcsNuls_nbre")
# Sélection données utiles
pourmoyennesCAH <- na.omit(subset(PourCAH_ttes_var, COM_NOUV == "OUI"))
somme_inscr_CFus <- sum(pourmoyennesCAH[, paste0(elect, "_Inscr_nbre")])
somme_inscr_ttes_com <- sum(na.omit(PourCAH_ttes_var[, paste0(elect, "_Inscr_nbre")]))
moyennesCAH <- data.frame()
i <- VarCAHBrutes[3]
for (i in VarCAHBrutes){
somme_ttes_com <- sum(PourCAH_ttes_var[, i], na.rm = TRUE)
moy_ttes_com <- round(100*somme_ttes_com/somme_inscr_ttes_com, 2)
somme_CFus <- sum(pourmoyennesCAH[, i], na.rm = TRUE)
moy_Cfus <- round(100*somme_CFus/somme_inscr_CFus, 2)
variable <- selecVarCAH[ which(VarCAHBrutes == i) ]
ligne <- c(variable, moy_ttes_com, moy_Cfus)
moyennesCAH <- rbind(moyennesCAH, ligne, stringsAsFactors= FALSE)
}
rm (somme_inscr_CFus, somme_inscr_ttes_com, somme_ttes_com, moy_ttes_com, somme_CFus, moy_Cfus, ligne, variable)
colnames(moyennesCAH) <- c("Variable", "Ensemble_étudié", "CommunesFusionnantes")
moyennesCAH$Variable <- as.factor(moyennesCAH$Variable)
moyennesCAH$Ensemble_étudié <- as.numeric(moyennesCAH$Ensemble_étudié)
moyennesCAH$CommunesFusionnantes <- as.numeric(moyennesCAH$CommunesFusionnantes)
moyennesCAH$DiffComFusComFr <- moyennesCAH$CommunesFusionnantes - moyennesCAH$Ensemble_étudié
aa<- ggplot(data = moyennesCAH) +
geom_bar(aes(x = Variable, y = Ensemble_étudié), stat = "identity") + coord_flip() + ylab(espace)
bb <- ggplot(data = moyennesCAH) +
geom_bar(aes(x = Variable, y = CommunesFusionnantes), stat = "identity") + coord_flip() + ylab("Communes fusionnantes")
cc <- ggplot(data = moyennesCAH) +
geom_bar(aes(x = Variable, y = DiffComFusComFr), stat = "identity") + coord_flip() + ylab(paste0("Différence Communes fusionnantes - ", espace))
cowplot::plot_grid(aa, bb, cc, ncol = 1, nrow = 3)
rm(aa,bb,cc)
# On intègre ces données dans le tableau de départ
PourCAHz <- scale(PourCAH[,c(1:NbrVariables)])
PourCAHz <- as.data.frame(PourCAHz, stringsAsFactors = FALSE)
PourCAHz$Groupes <- PourCAH$Groupes
# PourCAH$Groupes <- factor(cluspop,
# levels = 1:nclass,
# labels = paste(NomsGroupesCAH))
PourCAHz$CODGEO <- row.names(PourCAHz)
# Calcul de la moyenne des variables
clusProfileStd <- aggregate(PourCAHz [, 1:NbrVariables],
by = list(PourCAH$Groupes),
mean)
colnames(clusProfileStd)[1] <- "Groupes"
clusLongStd <- melt(clusProfileStd, id.vars = "Groupes")
# clusLongStd <- merge(clusLongStd, ratio[, 1:2], by.x = "variable", by.y = "CODE") # Pour lisibilité du graphique
# colnames(clusLongStd)[4] <- "Variable"
ggplot(clusLongStd) +
geom_bar(aes(x = variable, y = value, fill = Groupes),
stat = "identity") +
# scale_fill_grey() +
scale_fill_manual(values=couleurs) +
facet_wrap(~ Groupes, labeller = labeller(Groupes = Groupes_nbr)) +
coord_flip() + theme_bw()
# Remettre groupes dans geomfus2011 pour cartographie
typo <- merge(geom2011, PourCAH[ , c("CODGEO","Groupes")], by = "CODGEO", all.y = TRUE)
# Si la cartographie la plus adaptée est celle avec les communes nouvelles (élections 2022 par exemple)
# typo <- merge(geom_new, PourCAH[ , c("CODGEO","Groupes")], by.x = "CODGEO_new", by.y = "CODGEO", all.y = TRUE)
## Carte Typoe nationale des communes fusionnées
# mf_export(x = typo, export = "svg", filename = "figures/TypoEspaceGeo.svg",
# width = 5, theme = "nevermind") # Si souhait d'export
par(mfrow = c(1, 1))
par(mar=c(0,0,1.2,0))
typo$CODE_DEPT <- substr(typo$CODGEO, start = 1, stop = 2)
departements <- unique(typo$CODE_DEPT) # Pas parfait si données _new
departements <- na.rm(departements)
dep_carto <- subset(dep, CODE_DEPT %in% departements)
geomCN_new_carto <- geomCN_new
geomCN_new_carto$dep <- substr(geomCN_new_carto$CODGEO_new, start = 1, stop = 2)
geomCN_new_carto <- subset(geomCN_new_carto, dep %in% departements)
plot(st_geometry(dep_carto), border = "#1A1A19", lwd = 1)
typoLayer(x = typo, var = "Groupes",
col = couleurs,
border = NA,
#legend.title = "Typologie des communes fusionnantes/nà partir de critères socio-économiques",
legend.title.cex = 0.7,
legend.values.cex = 0.6,
legend.pos = "left", add = T,
legend.values.order = levels(typo$Groupes))
layoutLayer(title = "Typologie exploratoire des communes à partir de données électorales",
# author = "G. Bideau, 2023.",
author = "[Anonymisé], 2024.",
tabtitle = TRUE, frame = FALSE, col = "white", coltitle = "black",
# sources = paste0("Sources : Ministère de l'intérieur, INSEE, IGN, 2024.\nVariables : ", paste0(selecVar, collapse = ", ")))
sources = "Sources : Ministère de l'intérieur, INSEE, IGN, 2024.\nVariables : Résultats du premier tour de l'élection présidentielle 2017.")
# sources = "Sources : INSEE, IGN, 2022.")
plot(st_geometry(geomCN_new_carto), border = "#1A1A19" , lwd = 1, add = TRUE)
# dev.off() # Si souhait d'export
Cf. R et espace, chapitre 6 https://r.developpez.com/tutoriels/programmation-graphe/livre-R-et-espace/?page=chapitre-6-analyses-factorielles
Permet de montrer graphiquement les plans factoriels
library(ade4)
PCA <- dudi.pca(PourCAHz[,1:5],
center = TRUE,
scale = TRUE,
scannf = FALSE,
nf = 2)
summaryPca <- data.frame(
EIG = PCA$eig,
PCTVAR = 100 * PCA$eig / sum(PCA$eig),
CUMPCTVAR = cumsum(100 * PCA$eig / sum(PCA$eig))
)
barplot(summaryPca$PCTVAR,
xlab = "Composantes",
ylab = "Pourcentage de la variance (inertie)",
names = paste("C", seq(1, nrow(summaryPca), 1)),
col = "black",
border = "white")
axisCoord <- PCA$co
s.class(PCA$li,
fac = as.factor(PourCAHz$Groupes))
plot(PCA$li, pch = 20)
abline(h=0, v=0)
À tester
PourCOA <- evol_deps[2:nrow(evol_deps), c(bornes, "Département")]
PourCOA <- subset(PourCOA, PourCOA$Département != "Paris" & PourCOA$Département != "Aveyron")
row.names(PourCOA) <- PourCOA$Département
COA <- dudi.coa(PourCOA[,1:length(bornes)],
scannf = FALSE,
nf = 2)
summaryCOA <- data.frame(
EIG = COA$eig,
PCTVAR = 100 * COA$eig / sum(COA$eig),
CUMPCTVAR = cumsum(100 * COA$eig / sum(COA$eig))
)
barplot(summaryCOA$PCTVAR,
xlab = "Composantes",
ylab = "Pourcentage de la variance (inertie)",
names = paste("C", seq(1, nrow(summaryCOA), 1)),
col = "black",
border = "white")
plot(COA$li, pch = 20, col = "grey40")
abline(h=0, v=0)
points(COA$co, type = "o", pch = 18, col = "black")
text(COA$co,
labels = row.names(COA$co),
cex = 0.8,
pos = c(rep(4, times = 3), 1, rep(4, times = 4), 3))
s.class(COA$li,
fac = as.factor(PourCAHz$Groupes))
plot(PCA$li, pch = 20)
abline(h=0, v=0)
st_write(obj = typo, dsn = paste0("sorties/typo_data_elect_", elect, "_", espace, "_", nclass, "k.gpkg"), layer = "typo", delete_layer = TRUE, quiet = TRUE)
# st_write(obj = typo, dsn = "sorties/typo_data_elect_Normandie_4classes_1erT2012.gpkg", layer = "typo", delete_layer = TRUE, quiet = TRUE)
# typo <- st_read("sorties/typo_data_elect_Normandie_4classes_1erT2012.gpkg", quiet = TRUE)
typo <- st_read("sorties/typo_data_elect_PR2017_T1_France_5k.gpkg", quiet = TRUE)
Dans le but de comparer un profil avec la moyenne française, on
extrait les données de chaque groupe défini par la CAH (données issues
de clusLong et clusProfile) et on les compile
dans un tableau contenant déjà les données des moyennes françaises et
des communes fusionnantes (moyennesCAH). En sortie, un
tableau est créé pour chaque groupe.
# Tableau pour comparaison entre les groupes
clusProfile2 <- as.data.frame(t(clusProfile))
colnames(clusProfile2) <- clusProfile2[1,]
clusProfile2 <- clusProfile2[ c(2:nrow(clusProfile2)),]
compare <- cbind(moyennesCAH, clusProfile2)
for (i in NomsGroupesCAH){
a <- which(colnames(compare)== i)
b <- as.numeric(compare[,a])
compare[,a] <- as.numeric(compare[,a])
compare[paste0(i,"_DiffAvecFrance")] <- b - compare$Ensemble_étudié
compare[paste0(i,"_DiffAvecComFus")] <- b - compare$CommunesFusionnantes
rm(a, b)
}
kable(compare, row.names = F, digits = 2, caption = "Tableau de comparaison entre les groupes")
| Variable | Ensemble_étudié | CommunesFusionnantes | DiffComFusComFr | Groupe 1 | Groupe 2 | Groupe 3 | Groupe 4 | Groupe 5 | Groupe 1_DiffAvecFrance | Groupe 1_DiffAvecComFus | Groupe 2_DiffAvecFrance | Groupe 2_DiffAvecComFus | Groupe 3_DiffAvecFrance | Groupe 3_DiffAvecComFus | Groupe 4_DiffAvecFrance | Groupe 4_DiffAvecComFus | Groupe 5_DiffAvecFrance | Groupe 5_DiffAvecComFus |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| PR2017_T1_Abst_prct_insc | 19.92 | 17.84 | -2.08 | 14.66 | 15.01 | 15.48 | 15.70 | 22.42 | -5.26 | -3.18 | -4.91 | -2.83 | -4.44 | -2.36 | -4.22 | -2.14 | 2.50 | 4.58 |
| PR2017_T1_prct_insc_LE.PEN | 16.79 | 17.63 | 0.84 | 16.80 | 20.08 | 29.86 | 15.70 | 20.89 | 0.01 | -0.83 | 3.29 | 2.45 | 13.07 | 12.23 | -1.09 | -1.93 | 4.10 | 3.26 |
| PR2017_T1_prct_insc_FILLON | 15.51 | 17.22 | 1.71 | 16.83 | 27.02 | 14.75 | 11.31 | 13.60 | 1.32 | -0.39 | 11.51 | 9.80 | -0.76 | -2.47 | -4.20 | -5.91 | -1.91 | -3.62 |
| PR2017_T1_prct_insc_MÉLENCHON | 15.34 | 13.63 | -1.71 | 13.97 | 9.34 | 12.12 | 21.59 | 13.82 | -1.37 | 0.34 | -6.00 | -4.29 | -3.22 | -1.51 | 6.25 | 7.96 | -1.52 | 0.19 |
| PR2017_T1_prct_insc_MACRON | 18.63 | 18.78 | 0.15 | 21.73 | 14.73 | 13.60 | 17.35 | 14.70 | 3.10 | 2.95 | -3.90 | -4.05 | -5.03 | -5.18 | -1.28 | -1.43 | -3.93 | -4.08 |
| PR2017_T1_prct_insc_HAMON | 4.94 | 4.59 | -0.35 | 4.92 | 2.85 | 3.11 | 7.07 | 3.77 | -0.02 | 0.33 | -2.09 | -1.74 | -1.83 | -1.48 | 2.13 | 2.48 | -1.17 | -0.82 |
comparaisons <- data.frame()
for (i in NomsGroupesCAH){
a <- subset(typo, typo$Groupes == i)
Nb <- nrow(a)
c <- table(a$CATAEU2010)
h <- c(i, Nb, c)
comparaisons <- rbind(comparaisons, h, stringsAsFactors= FALSE)
rm( a, c, h, Nb)
}
colnames(comparaisons) <- c("Groupes", "Nombre", "111","112","120","211","212","221","222","300","400")
tmp <- comparaisons[, c("Groupes", "Nombre", "111","112","120","211","212","221","222","300","400")]
kable(tmp, row.names = F, digits = 1, caption = "Code de Zonage en aire urbaine dans chaque groupe",
col.names = c("Groupes", "Nombre de communes", "Unité urbaine", "Couronne périurbaine", "Communes multipolarisées", "Unité urbaine", "Couronne périurbaine", "Unité urbaine", "Couronne périurbaine", "Autres communes multipolarisées", "Communes hors influence des pôles"), format = "html") %>%
kableExtra::add_header_above(c(" " = 2, "Grandes aires urbaines" = 3, "Pôles moyens" = 2, "Petits pôles" = 2," " = 2))
| Groupes | Nombre de communes | Unité urbaine | Couronne périurbaine | Communes multipolarisées | Unité urbaine | Couronne périurbaine | Unité urbaine | Couronne périurbaine | Autres communes multipolarisées | Communes hors influence des pôles |
|---|---|---|---|---|---|---|---|---|---|---|
| Groupe 1 | 8899 | 1225 | 3639 | 639 | 128 | 235 | 194 | 137 | 1304 | 1398 |
| Groupe 2 | 5013 | 252 | 1322 | 502 | 28 | 100 | 80 | 69 | 1170 | 1490 |
| Groupe 3 | 9295 | 345 | 3730 | 1581 | 63 | 203 | 95 | 149 | 2089 | 1040 |
| Groupe 4 | 5357 | 375 | 1670 | 400 | 83 | 159 | 105 | 101 | 1054 | 1410 |
| Groupe 5 | 7312 | 1002 | 1741 | 806 | 136 | 99 | 375 | 94 | 1290 | 1769 |
x <- length(NomsGroupesCAH)
min <- min(compare[, (5+x):ncol(compare)])
max <- max(compare[, (5+x):ncol(compare)])
rm(x)
# Boucle donnant les valeurs pour chaque groupe, avec éléments de comparaison d'un profil avec la moyenne française
for (i in NomsGroupesCAH){
clusLongGr <- subset(clusLong, clusLong$Groupes == i)
compare <- merge(moyennesCAH, clusLongGr[, c("variable", "value")], by.x = "Variable", by.y = "variable")
compare$DiffAvecEns <- compare$value - compare$Ensemble_étudié
compare$DiffAvecComFus <- compare$value - compare$CommunesFusionnantes
compare[, 2:length(compare)] <- round(compare[, 2:length(compare)], 1)
n <- stringr::str_sub(i, 8, 8)
assign(paste0("compare_Gr", n), compare)
# print(kable(compare, row.names = F, caption = i))
colnames(compare) <- c ("Variable",
"Valeur pour l'ensemble étudié (A)",
"Valeur pour les communes fusionnantes (B)",
"Différence ComFus/Ensemble (B-A)",
"Valeur pour le groupe étudié (C)",
"Différence Groupe/Ensemble (C-A)",
"Différence Groupe/ComFus (C-B)")
# min <- min(compare[, c("Différence ComFus/Ensemble (B-A)", "Différence Groupe/Ensemble (C-A)", "Différence Groupe/ComFus (C-B)")])
# max <- max(compare[, c("Différence ComFus/Ensemble (B-A)", "Différence Groupe/Ensemble (C-A)", "Différence Groupe/ComFus (C-B)")])
table <- condformat(compare) %>%
rule_fill_bar("Valeur pour l'ensemble étudié (A)", limits = c(0, 100), low = "darkgreen", high = "darkgreen") %>%
rule_fill_bar("Valeur pour les communes fusionnantes (B)", limits = c(0, 100), low = "darkgreen", high = "darkgreen") %>%
rule_fill_bar("Valeur pour le groupe étudié (C)", limits = c(0, 100), low = "darkgreen", high = "darkgreen") %>%
rule_fill_gradient2("Différence ComFus/Ensemble (B-A)", low = "darkblue", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Différence Groupe/Ensemble (C-A)", low = "darkblue", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Différence Groupe/ComFus (C-B)", low = "darkblue", high = "red", limits = c(min, max))%>%
theme_caption(caption = i) %>%
theme_htmlWidget(number_of_entries = nrow(compare))
print(knit_print(table))
rm(compare, n, table)
}
[1] “
| Variable | Valeur pour l’ensemble étudié (A) | Valeur pour les communes fusionnantes (B) | Différence ComFus/Ensemble (B-A) | Valeur pour le groupe étudié (C) | Différence Groupe/Ensemble (C-A) | Différence Groupe/ComFus (C-B) | |
|---|---|---|---|---|---|---|---|
| 1 | PR2017_T1_Abst_prct_insc | 19.9 | 17.8 | -2.1 | 14.7 | -5.3 | -3.2 |
| 2 | PR2017_T1_prct_insc_FILLON | 15.5 | 17.2 | 1.7 | 16.8 | 1.3 | -0.4 |
| 3 | PR2017_T1_prct_insc_HAMON | 4.9 | 4.6 | -0.4 | 4.9 | 0.0 | 0.3 |
| 4 | PR2017_T1_prct_insc_LE.PEN | 16.8 | 17.6 | 0.8 | 16.8 | 0.0 | -0.8 |
| 5 | PR2017_T1_prct_insc_MACRON | 18.6 | 18.8 | 0.2 | 21.7 | 3.1 | 3.0 |
| 6 | PR2017_T1_prct_insc_MÉLENCHON | 15.3 | 13.6 | -1.7 | 14.0 | -1.4 | 0.3 |
| Variable | Valeur pour l’ensemble étudié (A) | Valeur pour les communes fusionnantes (B) | Différence ComFus/Ensemble (B-A) | Valeur pour le groupe étudié (C) | Différence Groupe/Ensemble (C-A) | Différence Groupe/ComFus (C-B) | |
|---|---|---|---|---|---|---|---|
| 1 | PR2017_T1_Abst_prct_insc | 19.9 | 17.8 | -2.1 | 15.0 | -4.9 | -2.8 |
| 2 | PR2017_T1_prct_insc_FILLON | 15.5 | 17.2 | 1.7 | 27.0 | 11.5 | 9.8 |
| 3 | PR2017_T1_prct_insc_HAMON | 4.9 | 4.6 | -0.4 | 2.8 | -2.1 | -1.7 |
| 4 | PR2017_T1_prct_insc_LE.PEN | 16.8 | 17.6 | 0.8 | 20.1 | 3.3 | 2.4 |
| 5 | PR2017_T1_prct_insc_MACRON | 18.6 | 18.8 | 0.2 | 14.7 | -3.9 | -4.0 |
| 6 | PR2017_T1_prct_insc_MÉLENCHON | 15.3 | 13.6 | -1.7 | 9.3 | -6.0 | -4.3 |
| Variable | Valeur pour l’ensemble étudié (A) | Valeur pour les communes fusionnantes (B) | Différence ComFus/Ensemble (B-A) | Valeur pour le groupe étudié (C) | Différence Groupe/Ensemble (C-A) | Différence Groupe/ComFus (C-B) | |
|---|---|---|---|---|---|---|---|
| 1 | PR2017_T1_Abst_prct_insc | 19.9 | 17.8 | -2.1 | 15.5 | -4.4 | -2.4 |
| 2 | PR2017_T1_prct_insc_FILLON | 15.5 | 17.2 | 1.7 | 14.7 | -0.8 | -2.5 |
| 3 | PR2017_T1_prct_insc_HAMON | 4.9 | 4.6 | -0.4 | 3.1 | -1.8 | -1.5 |
| 4 | PR2017_T1_prct_insc_LE.PEN | 16.8 | 17.6 | 0.8 | 29.9 | 13.1 | 12.2 |
| 5 | PR2017_T1_prct_insc_MACRON | 18.6 | 18.8 | 0.2 | 13.6 | -5.0 | -5.2 |
| 6 | PR2017_T1_prct_insc_MÉLENCHON | 15.3 | 13.6 | -1.7 | 12.1 | -3.2 | -1.5 |
| Variable | Valeur pour l’ensemble étudié (A) | Valeur pour les communes fusionnantes (B) | Différence ComFus/Ensemble (B-A) | Valeur pour le groupe étudié (C) | Différence Groupe/Ensemble (C-A) | Différence Groupe/ComFus (C-B) | |
|---|---|---|---|---|---|---|---|
| 1 | PR2017_T1_Abst_prct_insc | 19.9 | 17.8 | -2.1 | 15.7 | -4.2 | -2.1 |
| 2 | PR2017_T1_prct_insc_FILLON | 15.5 | 17.2 | 1.7 | 11.3 | -4.2 | -5.9 |
| 3 | PR2017_T1_prct_insc_HAMON | 4.9 | 4.6 | -0.4 | 7.1 | 2.1 | 2.5 |
| 4 | PR2017_T1_prct_insc_LE.PEN | 16.8 | 17.6 | 0.8 | 15.7 | -1.1 | -1.9 |
| 5 | PR2017_T1_prct_insc_MACRON | 18.6 | 18.8 | 0.2 | 17.3 | -1.3 | -1.4 |
| 6 | PR2017_T1_prct_insc_MÉLENCHON | 15.3 | 13.6 | -1.7 | 21.6 | 6.3 | 8.0 |
| Variable | Valeur pour l’ensemble étudié (A) | Valeur pour les communes fusionnantes (B) | Différence ComFus/Ensemble (B-A) | Valeur pour le groupe étudié (C) | Différence Groupe/Ensemble (C-A) | Différence Groupe/ComFus (C-B) | |
|---|---|---|---|---|---|---|---|
| 1 | PR2017_T1_Abst_prct_insc | 19.9 | 17.8 | -2.1 | 22.4 | 2.5 | 4.6 |
| 2 | PR2017_T1_prct_insc_FILLON | 15.5 | 17.2 | 1.7 | 13.6 | -1.9 | -3.6 |
| 3 | PR2017_T1_prct_insc_HAMON | 4.9 | 4.6 | -0.4 | 3.8 | -1.2 | -0.8 |
| 4 | PR2017_T1_prct_insc_LE.PEN | 16.8 | 17.6 | 0.8 | 20.9 | 4.1 | 3.3 |
| 5 | PR2017_T1_prct_insc_MACRON | 18.6 | 18.8 | 0.2 | 14.7 | -3.9 | -4.1 |
| 6 | PR2017_T1_prct_insc_MÉLENCHON | 15.3 | 13.6 | -1.7 | 13.8 | -1.5 | 0.2 |
” attr(,“class”) [1] “knit_asis” attr(,“…”) named list() attr(,“html”) [1] TRUE attr(,“knit_cacheable”) [1] NA
# Autre possibilité, qui m'a moins convaincue : https://cran.r-project.org/web/packages/kableExtra/vignettes/awesome_table_in_html.html#celltext_specification
# library(formattable)
# library(kableExtra)
# library(dplyr)
# compare_Gr2 %>%
# mutate (
# DiffComFusComFr = color_tile("white", "orange") (DiffComFusComFr),
# DiffAvecFr = color_tile("white", "orange") (DiffAvecFr),
# DiffAvecComFus = color_tile("white", "orange") (DiffAvecComFus),
# France = color_bar("lightgreen")(France),
# CommunesFusionnantes = color_bar("lightgreen")(CommunesFusionnantes),
# value = color_bar("lightgreen")(value)
# )%>%
# kable(escape = F, align = "r", digits = 1) %>%
# kable_styling(c("striped", "condensed"), full_width = F)
Il est important de préciser que, comme toujours, les détails des calculs statistiques ont toute leur importance. Jusqu’ici, les moyennes ont été calculées sur l’ensemble de la population des ensemble étudiés. Par exemple, le chiffre de 66,38 % d’actifs occupés hors de leur commune de résidence, désigne le nombre de personnes quittant leur commune pour aller travailler. Or, les chiffres sont différents si on fait, désormais, apparaître les moyennes des taux communaux d’actifs occupés hors de leur commune de résidence
# NB : On reprend les données déjà élaborées dans le 5.2.2
# Import données totales
# df2011_elect <- df2011_PR2017_T1 # Si utilisation des données communes/bureaux de vote à la géométrie 2011
# df2011_elect_Cfus <- subset(df2011_elect, df2011_elect$COM_NOUV == "OUI")
moyennesComCAH <- data.frame()
i <- selecVarCAH[1]
for (i in selecVarCAH){
a <- round(mean(PourCAH_ttes_var[, i], na.rm = TRUE), 2)
b <- round(median(PourCAH_ttes_var[, i], na.rm = TRUE), 2)
c <- round(mean(PourCAH_ttes_var[, i], na.rm = TRUE), 2)
d <- round(median(PourCAH_ttes_var[, i], na.rm = TRUE), 2)
h <- c(i, a, b, c, d)
moyennesComCAH <- rbind(moyennesComCAH, h, stringsAsFactors= FALSE)
rm( a, b, c, d, h)
}
# Pour calcul valeur moyenne retraités ("Inf" vient perturber) :
# a <- subset(df2011$P09_RETR1564_RT, df2011$P09_RETR1564_RT != Inf)
# mean(a, na.rm =TRUE)
# rm(a)
colnames(moyennesComCAH) <- c("Variable", "Comfr_moy", "Comfr_med", "Comfus_moy", "Comfus_med")
kable(moyennesComCAH[, 1:5], row.names = FALSE, col.names = c("", "Moyenne", "Médiane", "Moyenne", "Médiane"), digits = 2, format = "html") %>%
kableExtra::add_header_above(c("Variable" = 1, "Communes françaises" = 2, "Communes fusionnantes" = 2))
| Moyenne | Médiane | Moyenne | Médiane | |
|---|---|---|---|---|
| PR2017_T1_Abst_prct_insc | 16.66 | 16.31 | 16.66 | 16.31 |
| PR2017_T1_prct_insc_LE.PEN | 21.31 | 20.96 | 21.31 | 20.96 |
| PR2017_T1_prct_insc_FILLON | 16.23 | 15.33 | 16.23 | 15.33 |
| PR2017_T1_prct_insc_MÉLENCHON | 13.95 | 13.49 | 13.95 | 13.49 |
| PR2017_T1_prct_insc_MACRON | 16.56 | 16.3 | 16.56 | 16.3 |
| PR2017_T1_prct_insc_HAMON | 4.25 | 3.95 | 4.25 | 3.95 |
On observe la place des communes fusionnantes dans chaque groupe. On met également un place un test de chi² pour voir si on peut rejetter l’hypothèse d’indépendance des variables.
# typo <- st_read("sorties/typo_data_elect.gpkg", quiet = TRUE)
# typo <- st_read("sorties/typo_data_elect_Normandie_4classes_1erT2012.gpkg", quiet = TRUE)
tabcont <- table(typo$COM_NOUV, typo$Groupes)
tabcont # En valeur absolue
##
## Groupe 1 Groupe 2 Groupe 3 Groupe 4 Groupe 5
## NON 8148 4584 8886 5062 6844
## OUI 751 429 409 295 468
round(100*prop.table(tabcont,margin=1),1) # Pourcentages, le total se fait par lignes
##
## Groupe 1 Groupe 2 Groupe 3 Groupe 4 Groupe 5
## NON 24.3 13.7 26.5 15.1 20.4
## OUI 31.9 18.2 17.4 12.5 19.9
round(100*prop.table(tabcont,margin=),1) # Pourcentages, le total se fait sur l'ensemble de la population
##
## Groupe 1 Groupe 2 Groupe 3 Groupe 4 Groupe 5
## NON 22.7 12.8 24.8 14.1 19.1
## OUI 2.1 1.2 1.1 0.8 1.3
round(100*prop.table(tabcont,margin=2),1) # Pourcentages, le total se fait par colonnes
##
## Groupe 1 Groupe 2 Groupe 3 Groupe 4 Groupe 5
## NON 91.6 91.4 95.6 94.5 93.6
## OUI 8.4 8.6 4.4 5.5 6.4
test<-chisq.test(tabcont)
test$observed
##
## Groupe 1 Groupe 2 Groupe 3 Groupe 4 Groupe 5
## NON 8148 4584 8886 5062 6844
## OUI 751 429 409 295 468
round(test$expected,1)
##
## Groupe 1 Groupe 2 Groupe 3 Groupe 4 Groupe 5
## NON 8315.6 4684.4 8685.6 5005.8 6832.6
## OUI 583.4 328.6 609.4 351.2 479.4
round(test$residuals,2)
##
## Groupe 1 Groupe 2 Groupe 3 Groupe 4 Groupe 5
## NON -1.84 -1.47 2.15 0.79 0.14
## OUI 6.94 5.54 -8.12 -3.00 -0.52
test
##
## Pearson's Chi-squared test
##
## data: tabcont
## X-squared = 164.73, df = 4, p-value < 2.2e-16
Test de Chi² avec des variables du 1er et du 2e tour de 2012 : Maine-et-Loire (X-squared = 7.3037, df = 3, p-value = 0.06282) et Normandie (X-squared = 2.1736, df = 5, p-value = 0.8246) : Résultats non significatifs.
Test de Chi² sur Normandie avec que des variables au premier tour de 2012 : X-squared = 17.898, df = 5, p-value = 0.003077
Test de Chi² sur Maine-et-Loire avec que des variables au premier tour de 2012 : X-squared = 16.862, df = 4, p-value = 0.002056
Test de Chi² avec que des variables du premier tour en 2022 : Maine-et-Loire X-squared = 3.3623, df = 4, p-value = 0.4991, Normandie X-squared = 88.394, df = 5, p-value < 2.2e-16
Test de Chi² avec variables 1e tour 2012 (“PR2012_T1_Abst_prct_insc”, “PR2012_T1_prct_insc_LE.PEN”, “PR2012_T1_prct_insc_SARKOZY”, “PR2012_T1_prct_insc_MÉLENCHON”, “PR2012_T1_prct_insc_BAYROU”, “PR2012_T1_prct_insc_HOLLANDE”) et 4 groupes :
Maine-et-Loire :
Normandie : X-squared = 13.826, df = 3, p-value = 0.003152
À partir de la typologie réalisée, permettant de catégoriser les communes sur la base de données électorales, nous pouvons étudier la composition des communes nouvelles sur ce plan.
NB : Partie suivante doit être jouée seulement quand il y a des communes nouvelles ayant fusionné dans la typo (à la date des élections utilisées pour réaliser la typo) ?
# typo <- merge (typo, df2011[, c("CODGEO", "CODGEO_new")], by = "CODGEO", all.x = TRUE)
# typo <- st_read("sorties/typo_data_elect.gpkg", quiet = TRUE)
typo$Groupes <- as.factor(typo$Groupes) # On met la variable Groupes en facteur pour permettre la création du tableau
# NB : On supprime les communes n'étant pas des communes fusionnantes pour étudier celles-ci en particulier
typo_Cfus <- subset (typo, typo$COM_NOUV == "OUI")
# Définition d'un tableau comportant le nombre de communes fusionnantes par commune nouvelle
count_CN_typo <- plyr::count(typo_Cfus, "CODGEO_new")
mesCommunes <- count_CN_typo$CODGEO_new
# mesCommunes <- c("61324","73150","73006")
#pourinfo <- subset (typo, CODGEO_new == "61324" | CODGEO_new =="73150" | CODGEO_new == "73006")
df <- typo_Cfus
results <- data.frame(matrix(ncol=nclass, nrow=0))
i <- mesCommunes[1]
i <- "61324"
for (i in mesCommunes) { # Pour chaque identifiant de commune nouvelle,
toto <- subset (df, CODGEO_new == i ) # Ne garder que les communes fusionnantes y ayant participé
a <- table(toto$Groupes) # Relever les groupes des communes fusionnantes
results <- rbind(results,a) # Combiner les résultats, par lignes
rm(a, toto) # Supprimer "a"
}
# On renomme les colonnes
colnames(results) <- NomsGroupesCAH
count_CN_typo <- cbind(count_CN_typo, results)
# On identifie la variable la plus fréquente
count_CN_typo$max2 <- apply(count_CN_typo[, 3:(nclass+2)], 1, function(x) max(x, na.rm = TRUE))
# Quel est le groupe de typo revenant le plus fréquemment dans une CN
count_CN_typo$Typomaj <- colnames(count_CN_typo[, 3:(nclass+2)])[apply(count_CN_typo[, 3:(nclass+2)], 1, which.max)]
# On note si une CN a des communes fusionnantes avec un groupe de typo identique
count_CN_typo$TypoIdent <- ifelse(count_CN_typo$max == count_CN_typo$freq, TRUE, FALSE)
# summary(count_CN_typo$TypoIdent)
a <- summary(count_CN_typo$TypoIdent)
# On note si une CN a des communes fusionnantes avec un groupe de typo presque identique (max 25% de communes ayant un type différent)
count_CN_typo$TypopresqIdent <- ifelse((count_CN_typo$freq - count_CN_typo$max2)/count_CN_typo$freq <= 0.25, TRUE, FALSE)
# summary(count_CN_typo$TypopresqIdent)
b <- summary(count_CN_typo$TypopresqIdent)
tableau <- data.frame(rbind (a, b))
tableau$Mode <- c("Toutes les communes composant une commune nouvelle ont un groupe identique", "Au moins 75% des communes composant une commune nouvelle ont un groupe identique")
colnames(tableau)<- c("", "Faux", "Vrai")
kable(tableau, align = "c", digits = 0, row.names = FALSE)
| Faux | Vrai | |
|---|---|---|
| Toutes les communes composant une commune nouvelle ont un groupe identique | 482 | 358 |
| Au moins 75% des communes composant une commune nouvelle ont un groupe identique | 444 | 396 |
# On extrait les CN ayant des communes fusionnante avec un groupe de typo identique
CNTypoIdent <- subset(count_CN_typo, TypoIdent==TRUE)
CNTypoIdent <- merge(CNTypoIdent, typo[, c("CODGEO", "Groupes")], by.x = "CODGEO_new", by.y = "CODGEO", all.x = TRUE)
# Quel pourcentage de chaque groupe dans les communes nouvelles homogènes ?
tabcont<-summary(CNTypoIdent$Groupes)
# Quel pourcentage de chaque groupe est majoritaire ?
count_CN_typo$Typomaj <- as.factor(count_CN_typo$Typomaj)
tabcont2<-summary(count_CN_typo$Typomaj)
# Pour comparaison : pourcentages de chaque groupe dans les communes fusionnantes
tabcont3<-summary(typo_Cfus$Groupes)
round(100*prop.table(tabcont,margin=),1) # Pourcentages de chaque groupe en fonction de la totalité des communes nouvelles homogènes
## Groupe 1 Groupe 2 Groupe 3 Groupe 4 Groupe 5 NA's
## 34.6 12.6 15.9 12.8 15.4 8.7
round(100*prop.table(tabcont2,margin=),1) # Pourcentages de chaque groupe majoritaire en fonction de la totalité des communes fusionnantes
## Groupe 1 Groupe 2 Groupe 3 Groupe 4 Groupe 5
## 45.2 16.3 15.7 11.0 11.8
round(100*prop.table(tabcont3,margin=),1) # Pourcentages de chaque groupe en fonction de la totalité des communes fusionnantes
## Groupe 1 Groupe 2 Groupe 3 Groupe 4 Groupe 5
## 31.9 18.2 17.4 12.5 19.9
tableau <- rbind(
summary(CNTypoIdent$Groupes),
round(summary(CNTypoIdent$Groupes) * 100 / length(unique(typo_Cfus$CODGEO_new)),1),
round(100*prop.table(tabcont,margin=),1),
summary(count_CN_typo$Typomaj),
round(summary(count_CN_typo$Typomaj) * 100 /length(unique(typo_Cfus$CODGEO_new)),1),
summary(typo_Cfus$Groupes),
round(100*prop.table(tabcont3,margin=),1)
)
row.names(tableau) <- c(
"Nombre de communes nouvelles regroupant des communes homogènes du point de vue de la typologie",
"Pourcentages en fonction de la totalité des communes nouvelles",
"Pourcentages en fonction de la totalité des communes nouvelles homogènes",
"Nombre de communes nouvelles ayant ce groupe comme type majoritaire (tous ont un groupe maj)",
"Pourcentages des CN majoritaires en fonction de la totalité des communes nouvelles",
"Nombre de communes fusionnantes par groupe",
"Pourcentages de chaque groupe en fonction de la totalité des communes fusionnantes"
)
kable(tableau, align = "c", digits = c(0, 1, 1, 0, 1, 0, 1)
)
| Groupe 1 | Groupe 2 | Groupe 3 | Groupe 4 | Groupe 5 | NA’s | |
|---|---|---|---|---|---|---|
| Nombre de communes nouvelles regroupant des communes homogènes du point de vue de la typologie | 124 | 45.0 | 57.0 | 46 | 55.0 | 31 |
| Pourcentages en fonction de la totalité des communes nouvelles | 15 | 5.4 | 6.8 | 6 | 6.5 | 4 |
| Pourcentages en fonction de la totalité des communes nouvelles homogènes | 35 | 12.6 | 15.9 | 13 | 15.4 | 9 |
| Nombre de communes nouvelles ayant ce groupe comme type majoritaire (tous ont un groupe maj) | 380 | 137.0 | 132.0 | 92 | 99.0 | 380 |
| Pourcentages des CN majoritaires en fonction de la totalité des communes nouvelles | 45 | 16.3 | 15.7 | 11 | 11.8 | 45 |
| Nombre de communes fusionnantes par groupe | 751 | 429.0 | 409.0 | 295 | 468.0 | 751 |
| Pourcentages de chaque groupe en fonction de la totalité des communes fusionnantes | 32 | 18.2 | 17.4 | 12 | 19.9 | 32 |
print("\n*ATTENTION, variables NA's non valables pour les lignes du tableau concernant les majoritaires (potentiellement complétées par la première valeur de la ligne).*")
## [1] "\n*ATTENTION, variables NA's non valables pour les lignes du tableau concernant les majoritaires (potentiellement complétées par la première valeur de la ligne).*"
On souhaite regarder en moyenne avec quelles communes certains groupes s’apparient. On souhaite, en particulier, regarder les groupes qui feraient particulièrement ressortir les extrêmes et/ou l’abstention.
table(typo$Groupes)
##
## Groupe 1 Groupe 2 Groupe 3 Groupe 4 Groupe 5
## 8899 5013 9295 5357 7312
results <- data.frame()
for (Groupe_etud in levels(typo$Groupes)) {
count_CN_typo_subset <- subset(count_CN_typo, count_CN_typo[, Groupe_etud] > 0)
nbr_com <- apply(count_CN_typo_subset[, levels(typo$Groupes)], 2, sum)
nbr_moy_com <- round(apply(count_CN_typo_subset[, levels(typo$Groupes)], 2, mean), 2)
result <- c(Groupe_etud, nbr_com, nbr_moy_com)
results <- rbind(results, result, stringsAsFactors= FALSE)
}
colnames(results) <- c("Groupe étudié", paste0("Nombre de communes associées\n(", NomsGroupesCAH, ")"), paste0("Moyenne de communes associées\n(", NomsGroupesCAH, ")"))
results$`Nombre de communes fusionnantes` <- table(typo_Cfus$Groupes)
kable(results)
|Groupe étudié |Nombre de communes associées (Groupe 1) |Nombre de communes associées (Groupe 2) |Nombre de communes associées (Groupe 3) |Nombre de communes associées (Groupe 4) |Nombre de communes associées (Groupe 5) |Moyenne de communes associées (Groupe 1) |Moyenne de communes associées (Groupe 2) |Moyenne de communes associées (Groupe 3) |Moyenne de communes associées (Groupe 4) |Moyenne de communes associées (Groupe 5) | Nombre de communes fusionnantes| |:————-|:————————————–|:————————————–|:————————————–|:————————————–|:————————————–|:—————————————|:—————————————|:—————————————|:—————————————|:—————————————|——————————-:| |Groupe 1 |751 |213 |128 |126 |194 |1.67 |0.47 |0.28 |0.28 |0.43 | 751| |Groupe 2 |202 |429 |149 |32 |137 |0.83 |1.76 |0.61 |0.13 |0.56 | 429| |Groupe 3 |111 |140 |409 |38 |163 |0.44 |0.56 |1.64 |0.15 |0.65 | 409| |Groupe 4 |157 |44 |34 |295 |93 |0.77 |0.22 |0.17 |1.45 |0.46 | 295| |Groupe 5 |190 |144 |181 |92 |468 |0.61 |0.46 |0.58 |0.29 |1.49 | 468|
Non joué car on ne dispose pas nécessairement de la distance euclidienne adaptée à nos données.
# Import des données concernant la typologie
typo <- st_read("sorties/typo_data_elect.gpkg", quiet = TRUE)
# typo <- subset(typo, ChefLieu == "O")
# count_CN_typo <- plyr::count(typo, "CODGEO_new")
disteucl <- st_read("sorties/disteucl.gpkg", layer = "disteucl", quiet = TRUE)
disteucl <- merge (disteucl, count_CN_typo, by = "CODGEO_new", all.y = FALSE)
GroupesDisteucl <- by(disteucl$dist_CN, disteucl$Typomaj, mean, na.rm = TRUE)
GroupesDisteucl <- data.frame(as.table (GroupesDisteucl))
colnames(GroupesDisteucl) <- c("Typomaj", "mean")
GroupesDisteucl$sd <- as.numeric(by(disteucl$dist_CN, disteucl$Typomaj, sd, na.rm = TRUE))
GroupesDisteucl$median <- as.numeric(by(disteucl$dist_CN, disteucl$Typomaj, median, na.rm = TRUE))
# On rajoute les valeurs moyennes pour faciliter les comparaisons
levels(GroupesDisteucl$Typomaj) <- c(levels (GroupesDisteucl$Typomaj), "Ensemble")
GroupesDisteucl[ nrow(GroupesDisteucl)+1, ] <- c("Ensemble",
mean(disteucl$dist_CN, na.rm = TRUE),
sd(disteucl$dist_CN, na.rm = TRUE),
median(disteucl$dist_CN, na.rm = TRUE))
# Esthétique pour faciliter la lecture
GroupesDisteucl[, 2] <- as.numeric(GroupesDisteucl[, 2])
GroupesDisteucl[, 3] <- as.numeric(GroupesDisteucl[, 3])
GroupesDisteucl[, 4] <- as.numeric(GroupesDisteucl[, 4])
GroupesDisteucl[, 2:4] <- round(GroupesDisteucl[, 2:4], 1)
tmp <- GroupesDisteucl
colnames(tmp) <- c("Groupe majoritaire dans la commune nouvelle", "Moyenne", "Écart-type", "Médiane")
kable(tmp, row.names = F, digits = 1, caption = "Typologie et distance euclidienne intra-communes nouvelles")
condformat(tmp[, c(1,2, 4)]) %>%
rule_fill_gradient2("Moyenne", low = "darkblue", high = "red", limits = c(min (tmp$Moyenne), max (tmp$Moyenne))) %>%
rule_fill_gradient2("Médiane", low = "darkblue", high = "red", limits = c(min(tmp$Médiane), max(tmp$Médiane))) %>%
theme_caption(caption = "Typologie et distance euclidienne intra-communes nouvelles") %>%
theme_htmlWidget(number_of_entries = nrow(tmp))
L’observation de la distance euclidienne en fonction des catégories de communes précédemment élaborés permet de visualiser les différences entre les groupes. Les communes dont le type majoritaire est le 1 et le 2, par exemple, sont en moyenne plus homogènes que les communes nouvelles où les groupes 3, 5 et surtout 4 dominent.
# Création d'une variable surface
# Si on part de rien, jouer les deux lignes ci-dessous
# typo <- st_read("sorties/typo_data_elect.gpkg", quiet = TRUE)
comparaisons <- data.frame( table (typo$Groupes))
# Création d'une variable de surface
typo$surface <- st_area(typo) # Attention, unités : m²
typo$surface <- set_units(typo$surface, km^2) # On passe en km²
typo$densite <- typo$P09_POP/typo$surface
comparaisons$surface_moy <- round(tapply (typo$surface, typo$Groupes, mean), 2) # On fait la moyenne de la surface
comparaisons$surface_med <- round(tapply (typo$surface, typo$Groupes, median), 2) # On fait la médiane de la surface
comparaisons$pop_moy <- round(tapply (typo$P09_POP, typo$Groupes, mean), 2) # On fait la moyenne de la population
comparaisons$pop_med <- round(tapply (typo$P09_POP, typo$Groupes, median), 2) # On fait la médiane de la population
comparaisons$dens_moy <- round(tapply (typo$densite, typo$Groupes, mean), 2) # On fait la moyenne de la population
comparaisons$dens_med <- round(tapply (typo$densite, typo$Groupes, median), 2) # On fait la médiane de la population
tmp <- comparaisons[, c("Var1", "Freq", "surface_moy", "surface_med", "pop_moy", "pop_med", "dens_moy", "dens_med")]
colnames(tmp) <- c("Groupe", "Fréquence", "Surface moyenne (km²)", "Surface médiane (km²)", "Population moyenne", "Population médiane", "Densité moyenne", "Densité médiane")
table <- condformat(tmp)%>%
rule_fill_gradient2("Surface moyenne (km²)", low = "blue", high = "red") %>%
rule_fill_gradient2("Surface médiane (km²)", low = "blue", high = "red") %>%
rule_fill_gradient2("Population moyenne", low = "blue", high = "red") %>%
rule_fill_gradient2("Population médiane", low = "blue", high = "red") %>%
rule_fill_gradient2("Densité moyenne", low = "blue", high = "red") %>%
rule_fill_gradient2("Densité médiane", low = "blue", high = "red") %>%
theme_caption(caption = "Groupes de la typologie vis-à-vis de la surface et de la population des communes fusionnantes") %>%
theme_htmlWidget(number_of_entries = nrow(tmp))
print(table)
# On liste, pour chaque région, le nombre de communes appartenant à chaque groupe
typoregions <- data.frame(table(typo$REG, typo$Groupes))
# Import d'un fichier donnant le nom des régions en fonction de leur code : https://www.insee.fr/fr/information/2560625#titre-bloc-29
names <- data.frame(read_excel("data-raw/stats_insee/table-appartenance-geo-communes-11.xls", sheet = "Niv_supracom", skip = 5))
names <- subset(names , names$NIVGEO == "REG")
typoregions <- merge (typoregions, names[, c("CODGEO", "LIBGEO")], by.x = "Var1", by.y = "CODGEO", all.x = TRUE, all.y = FALSE)
# Pour avoir les groupes en colonnes, plus pertinent de le faire avant l'ajout des noms
typoregions1 <- dcast(typoregions, LIBGEO ~ Var2, value.var = "Freq")
# Pour avoir les régions en colonnes
typoregions2 <- dcast(typoregions, Var2 ~ LIBGEO, value.var = "Freq")
min <- min(typoregions1[, 2:ncol(typoregions1)])
max <- max(typoregions1[, 2:ncol(typoregions1)])
# Si le format choisi est avec les groupes en colonnes
table <- condformat(typoregions1) %>% # ici les couleurs sont définies par les limites min/max
rule_fill_gradient2("Groupe 1 PPCQ", low = "white", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Groupe 2 PFO", low = "white", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Groupe 3 MOARO", low = "white", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Groupe 4 VAR", low = "white", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Groupe 5 REAV", low = "white", high = "red", limits = c(min, max))
print(table)
table2 <- condformat(typoregions1) %>% # ici les couleurs sont les min/max automatiques, par colonnes
rule_fill_gradient2("Groupe 1 PPCQ", low = "blue", high = "red") %>%
rule_fill_gradient2("Groupe 2 PFO", low = "blue", high = "red") %>%
rule_fill_gradient2("Groupe 3 MOARO", low = "blue", high = "red") %>%
rule_fill_gradient2("Groupe 4 VAR", low = "blue", high = "red") %>%
rule_fill_gradient2("Groupe 5 REAV", low = "blue", high = "red")
print(table2)
# Si le format choisi est avec les régions en colonnes
table3 <- condformat(typoregions2) %>% # ici les couleurs sont les min/max automatiques, par colonnes
rule_fill_gradient2("Alsace", low = "white", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Aquitaine", low = "white", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Auvergne", low = "white", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Basse-Normandie", low = "white", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Bourgogne", low = "white", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Bretagne", low = "white", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Centre", low = "white", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Champagne-Ardenne", low = "white", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Franche-Comté", low = "white", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Haute-Normandie", low = "white", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Île-de-France", low = "white", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Languedoc-Roussillon", low = "white", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Limousin", low = "white", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Lorraine", low = "white", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Midi-Pyrénées", low = "white", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Nord-Pas-de-Calais", low = "white", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Pays de la Loire", low = "white", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Picardie", low = "white", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Poitou-Charentes", low = "white", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Provence-Alpes-Côte d'Azur", low = "white", high = "red", limits = c(min, max)) %>%
rule_fill_gradient2("Rhône-Alpes", low = "white", high = "red", limits = c(min, max))
print(table3)
table4 <- condformat(typoregions2) %>% # ici les couleurs sont les min/max automatiques, par colonnes
rule_fill_gradient2("Alsace", low = "white", high = "red") %>%
rule_fill_gradient2("Aquitaine", low = "white", high = "red") %>%
rule_fill_gradient2("Auvergne", low = "white", high = "red") %>%
rule_fill_gradient2("Basse-Normandie", low = "white", high = "red") %>%
rule_fill_gradient2("Bourgogne", low = "white", high = "red") %>%
rule_fill_gradient2("Bretagne", low = "white", high = "red") %>%
rule_fill_gradient2("Centre", low = "white", high = "red") %>%
rule_fill_gradient2("Champagne-Ardenne", low = "white", high = "red") %>%
rule_fill_gradient2("Franche-Comté", low = "white", high = "red") %>%
rule_fill_gradient2("Haute-Normandie", low = "white", high = "red") %>%
rule_fill_gradient2("Île-de-France", low = "white", high = "red") %>%
rule_fill_gradient2("Languedoc-Roussillon", low = "white", high = "red") %>%
rule_fill_gradient2("Limousin", low = "white", high = "red") %>%
rule_fill_gradient2("Lorraine", low = "white", high = "red") %>%
rule_fill_gradient2("Midi-Pyrénées", low = "white", high = "red") %>%
rule_fill_gradient2("Nord-Pas-de-Calais", low = "white", high = "red") %>%
rule_fill_gradient2("Pays de la Loire", low = "white", high = "red") %>%
rule_fill_gradient2("Picardie", low = "white", high = "red") %>%
rule_fill_gradient2("Poitou-Charentes", low = "white", high = "red") %>%
rule_fill_gradient2("Provence-Alpes-Côte d'Azur", low = "white", high = "red") %>%
rule_fill_gradient2("Rhône-Alpes", low = "white", high = "red") %>%
print(table4)
# On liste, pour chaque département, le nombre de communes appartenant à chaque groupe
# méthode #
dep_typo <- unique(typo$CODE_DEPT)
typodep <- data.frame()
for (i in dep_typo) {
numero <- i
subset <- subset (typo, CODE_DEPT == i)
b <- table(subset$Groupes)
resultdep <- c(numero, b)
typodep <- rbind (typodep, resultdep, stringsAsFactors = FALSE)
rm(numero, subset, b, resultdep)
}
# méthode 2 (revient au môme)
typodep <- data.frame(table(typo$CODE_DEPT, typo$Groupes))
typodep <- dcast(typodep, Var1 ~ Var2)
# Cartographie
dep <- merge(dep, typodep, by.x = "CODE_DEPT", by.y = "Var1", all.x = TRUE)
dep[is.na(dep)] <- 0
# Manipulation des noms de groupes car sinon variables non reconnues
NomsGroupesCAH2 <- str_replace_all(NomsGroupesCAH, " ", "_")
colnames(dep)[3:7] <- NomsGroupesCAH2
par(mfrow=c(2,3))
for (i in NomsGroupesCAH2) {
plot(st_geometry(dep))
propSymbolsLayer(x = dep,
var = i, symbols ="circle",
col = "#B00EF0",
legend.pos = "left",
legend.title.txt = "Nombre de communes fusionnantes", inches = 0.2, fixmax = 150)
}
Pour les élections avant et après les fusions : les communes fusionnantes et nouvelles se positionnent-elles différemment des autres communes comparables ?
Cf. par exemple https://larmarange.github.io/analyse-R/regression-logistique.html.
On fait le choix d’analyser ces données sous l’angle d’une régression logistique. Il s’agit d’observer si des variables augmentent ou diminuent la probabilité d’avoir une situation (fusion ou non). (Les tests de régression logistique sont utilisées parfois pour observer si des caractéristiques, qui seraient donc alors des comorbidités, augmentent ou non la probabilité d’avoir un décès.)
Les variables explicatives envisagées sont celles qui ont été pointées comme caractérisant davantage les communes nouvelles lors des études univariées, bivariées, ou lors de catégorisations [@bideau2019, @bideau2022c].
Le choix des variables explicatives envisagées est déterminant, comme cela a pu être montré par exemple par @afsa2016. En effet, le modèle logit présente la probabilité d’estimer la probabilité qu’un évènement se produise (dans notre cas, fusion ou non) mais il seulement en prenant en compte les données présentes dans le modèle. Dans le cas présenté par @afsa2016, si on n’intègre pas les CSP des parents, le fait d’être en ZEP a un impact très négatif sur l’orientation en second. Si on intègre ces CSP, la significativité de la ZEP disparaît presque intégralement, si on ajoute le niveau en 6e, le fait d’être en ZEP redevient significatif mais un facteur favorable pour cette orientation.
# Si l'on souhaite avoir des noms de variables plus explicites, il faut ajouter des étiquettes des variables avec var_label de l'extension labelled. Par exemple :
# var_label(d$sport) <- "Pratique du sport ?"
Il est d’abord pertinent de vérifier que ce qui va être perçu, dans notre variable d’intérêt (ici la fusion ou non) comme la modalité de référence est bien la situation normale, la plus fréquente. Dans notre cas, la très grandes majorité des communes françaises n’a pas connu de fusion, c’est donc la non-fusion qui est notre modalité de référence.
knitr::opts_chunk$set(echo=FALSE, # Afficher ou non le code R dans le document
eval = FALSE, # Exécuter ou non le code R à la compilation
include = FALSE, # Inclure ou non le code R et ses résultats dans le document
# results “hide”/“asis”/“markup”/“hold” Type de résultats renvoyés par le bloc de code
warning = TRUE, # Afficher ou non les avertissements générés par le bloc
message = TRUE, # Afficher ou non les messages générés par le bloc
cache = TRUE) # Utiliser le cache pour accélerer les knits.
Choix des variables qui doivent éviter celles pointées comme auto-corrélées plus haut. On affiche également le VIF pour limiter au maximum les biais d’interprétation.
NB : Toutes choses égales par ailleurs quand au ZAU et au département, la dimension politique ne paraît pas avoir d’impact significatif sur la probabilité de fusionner en Normandie quand on prend en compte les données du 1er tour de l’élection présidentielle de 2012.
Les odds ratio (littéralement rapport des cotes, ou rapport des chances ou rapport des risques relatiffs) permettent de décrire la significativité pratique. Celle-ci désigne l’impact d’une variable. Il ne faut pas la confondre avec la significativité statistique, qui décrit « le degré de certitude avec lequel on peut affirmer qu’une variable influe » (@afsa2016 p. 39).
À noter que, par exemple pour @afsa2016, l’expression « toutes choses égales par ailleurs » est à éviter. En effet, ce n’est le cas que si les variables étudiées permettent de décrire parfaitement le phénomène. « les résultats des estimations sont conditionnels à la liste des variables x introduites dans le modèle, c’est-à-dire qu’ils dépendent des variables introduites » (@afsa2016 p. 53). Si des variables, non mesurées, influent à la fois sur les variables du modèle et la variable étudiée, cela brouille l’analyse. Ainsi, pour les analyses présentées ici, c’est plutôt l’expression “Toutes choses égales quant aux autres variables introduites” qui est à utiliser.
Un Odds ratio égal à 1 signifie que la variable d’intérêt (la fusion ici) est indépendante de la variable explicative envisagée. Si l’OR est supérieur à 1, une commune ayant une variable explicative plus élevée ont plus de chance de fusionner, s’il est inférieur à 1, les communes avec une variable explicative plus faible ont moins de chance de fusionner.
Regarder un peu dans le détail les résultats de Cherbourg et Annecy : La fusion a-t-elle conduit à des basculements politiques ?
On pose la question suivante : Y a-t-il une différence entre
le candidat arrivé en tête dans chaque commune fusionnante ;
le candidat arrivé en tête en mélangeant tous les votes d’une commune nouvelle ?
Cela permettrait de mettre clairement en lumière l’effet de MAUP dans le cas des communes nouvelles.
Mais il faudrait avoir de la chance pour tomber sur une commune nouvelle où un candidat aurait perdu de peu dans chaque commune fusionnante mais pas devant le même adversaire et pourrait donc gagner au total.
www.interieur.gouv.fr/content/download/68541/499035/file/Absence%2520de%2520candidats%2520communes%2520moins%2520de%25201%2520000%2520hbts.pdf
NB : la presse parle de 64 communes dont une seule de plus de 1000 habitants. La liste du ministère de l’intérieur pour les communes de moins de 1000 habitants ne comprend que 61 communes. Conclusion : seulement onze des 61 communes concernées ont participé à une création de commune nouvelle (en 2019).
En revanche, relation a priori significative statistiquement.