1 Objectifs du présent document

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 () 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/

2 Préparation des données

2.1 Choix concernant les données utilisées en fonction des différentes élections

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.

Les données électorales utilisées en fonction des situations des communes
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.

2.2 Import de la base DAC

# 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

2.3 Téléchargement des données à l’échelle communale

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")

2.4 Mise en forme et rapides analyses des données des élections municipales

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).

2.4.1 Import des données brutes 2014

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)))

2.4.2 Import des données brutes 2020

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.

2.4.3 Mise en forme des données municipales

2.4.3.1 [2014] Communes de plus de 1000 habitants

# === 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])

2.4.3.2 [2020] Communes de plus de 1000 habitants

# === 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])

2.4.3.3 Abstention 2014 pour toutes les communes

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)

2.4.3.4 Abstention 2020 pour toutes les communes

# 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)

2.4.3.5 Sauvegarde des données municipales

# 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)

2.4.4 Analyse superficielle de la représentativité des données des élections municipales

# 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

2.4.5 Étude possible des communes fusionnantes de 1000 habitants ou plus

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)

2.5 Import des données des élections présidentielles et mise en forme

2.5.1 Données des élections présidentielles à l’échelle communale

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)

2.5.2 Données élections présidentielles par commune

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)

  }

2.5.3 Présidentielles à l’échelle des bureaux de vote

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

2.5.4 Données élections présidentielles par bureau de vote (tous bureaux)

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")

2.6 Travail sur les jonctions des bureaux de vote

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

2.6.1 Import des géométries 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) 

2.6.2 Jonction bureaux / geom

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.

2.6.3 Jonction des résultats des élections par bureaux de vote avec les géométries desdits bureaux

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.

2.6.4 Mise en forme des données des élections présidentielles par bureau de vote, spécifiquement pour les communes fusionnantes

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")

2.6.5 Compilation données pour obtenir les résultats à la géométrie 2011

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.”

2.7 Import des données mises en formes

2.7.1 Données à l’échelle communale

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)

2.7.2 Données des communes fusionnantes à partir des données à l’échelle des bureaux de vote

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)

2.7.3 Données mises en forme et recalculées à la géométrie 2011

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) 

2.7.4 Ébauche de cartographie

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.

3 Étude de la participation et de l’abstention

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.

3.1 Import des données de la base DAC

# 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

3.2 Import et préparation des données

# 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.

3.3 Étude de l’abstention en 2014

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)))

}

3.4 Étude de l’abstention en 2020

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)))

}

3.5 Création d’un tableau avec les données 2014 et 2020

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.

3.5.1 Création de la fonction adaptée

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)
  }

3.5.2 Application de la fonction à nos données

# 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"))

3.5.3 Sauvegarde des données

try(save(df2011_abst, df_new_abst, geom2011, geom_new, geomCN_new, geomfus2011, file = "data/refdata_abst.Rdata"))

load("data/refdata_abst.Rdata")

3.6 Régression logistique sur variables de la participation et l’abstention

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.

3.7 Évolution de l’abstention 2014-2020

3.7.1 Toutes communes

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.

3.7.2 Communes de moins de 1000 habitants

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

4 Politique et fusion : Quel est le profil politique des communes fusionnantes par rapport aux communes non fusionnantes

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” ?

4.1 Réalisation d’une typologie

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.

4.1.1 Préparation des données

# 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

4.1.2 Sélectionner les variables d’intérêt et le cadre d’étude

# É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)

4.1.3 Réalisation de la typologie et valeurs

4.1.3.1 Typologie par CAH

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")

4.1.3.2 Choix nombre de classes

# 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

4.1.3.3 Typologie par k-means

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

4.1.3.4 Valeurs absolues

# 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()

4.1.3.5 Valeurs moyennes

# 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)

4.1.3.6 Valeurs standardisées

# 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()

4.1.3.7 Cartographie

# 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

4.1.4 Présentation plan factoriel à partir d’une ACP et d’une AFC

Cf. R et espace, chapitre 6 https://r.developpez.com/tutoriels/programmation-graphe/livre-R-et-espace/?page=chapitre-6-analyses-factorielles

4.1.4.1 Réalisation d’une ACP

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)

4.1.4.2 Réalisation d’une AFC

À 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)

4.1.5 Export données typo

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)

4.1.6 Comparaison et analyse des groupes

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.

4.1.6.0.1 Comparaison tous groupes
# 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")
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)) 
Code de Zonage en aire urbaine dans chaque groupe
Grandes aires urbaines
Pôles moyens
Petits pôles
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
4.1.6.0.2 Tableaux comparaison groupe par groupe
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
” attr(,“class”) [1] “knit_asis” attr(,“…”) named list() attr(,“html”) [1] TRUE attr(,“knit_cacheable”) [1] NA [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 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
” attr(,“class”) [1] “knit_asis” attr(,“…”) named list() attr(,“html”) [1] TRUE attr(,“knit_cacheable”) [1] NA [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 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
” attr(,“class”) [1] “knit_asis” attr(,“…”) named list() attr(,“html”) [1] TRUE attr(,“knit_cacheable”) [1] NA [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 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
” attr(,“class”) [1] “knit_asis” attr(,“…”) named list() attr(,“html”) [1] TRUE attr(,“knit_cacheable”) [1] NA [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 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)
4.1.6.0.3 Comparaisons des moyennes

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))
Variable
Communes françaises
Communes fusionnantes
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

4.2 Analyse de la typologie

4.2.1 Quel poids des communes nouvelles dans chaque groupe ?

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

4.2.2 Chaque CN est-elle composée d’un seul type en fonction de la typologie réalisée ?

À 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).*"

4.2.3 Appariemment de groupes

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|

4.2.4 Typologie et distance euclidienne

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.

4.2.5 Typologie vis-à-vis de quelques autres données

# 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)
Groupes de la typologie vis-à-vis de la surface et de la population des communes fusionnantes
Groupe Fréquence Surface moyenne (km²) Surface médiane (km²) Population moyenne Population médiane Densité moyenne Densité médiane
1 Groupe 1 8899 15.30 11.04 2086.11 643 197.96 56.03
2 Groupe 2 5013 14.68 10.59 774.37 258 83.95 23.26
3 Groupe 3 9295 11.97 9.30 658.82 379 66.56 40.55
4 Groupe 4 5357 16.60 11.93 2113.67 348 191.81 28.16
5 Groupe 5 7312 17.30 12.50 3032.32 616 244.38 46.31
Showing 1 to 5 of 5 entries.
# 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)
}

4.2.6 Modélisation des relations statistiques (logit)

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.)

4.2.6.1 Variables explicatives envisagées

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 ?"

4.2.6.2 Modalités de la variable d’intérêt

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.

4.2.6.3 Mise en œuvre de la régression logistique

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.

4.2.6.4 Lecture du modèle

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.

5 Étude de cas particuliers

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

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.

6 Communes sans candidats aux élections municipales de 2014

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.