Nettoyer et standardiser avec R

Author

Noé Barthelemy - ISEE

I) Introduction

Vous le savez sûrement, mais toute analyse de données rigoureuse commence par un nettoyage des données. Cette étape cruciale permet de garantir la qualité et la fiabilité des résultats obtenus. Sans un nettoyage adéquat, plusieurs problèmes peuvent survenir :

  • Données manquantes : Les algorithmes peuvent produire des résultats biaisés ou imprécis si des valeurs sont manquantes.

  • Doublons : La duplication des données peut entraîner des erreurs dans les calculs et fausser les statistiques.

  • Formats incohérents : Des incohérences dans les formats (dates, nombres, textes) peuvent provoquer des erreurs lors de l’importation ou de l’analyse des données.

Prendre le temps de bien nettoyer les données permet d’assurer une analyse fluide et fiable, et d’éviter ces écueils qui peuvent compromettre la qualité des résultats. C’est aussi cela qui fera vraiment faire la différence entre un projet qui roule et un casse-tête sans fin.

Les symptômes courants des données mal nettoyées sont :

  • Des caractères spéciaux (par exemple, des virgules dans les valeurs numériques)

  • Des valeurs numériques stockées sous forme de texte/caractère

  • Des lignes en double

  • Des fautes d’orthographe

  • Des inexactitudes

  • Des espaces blancs

  • Des données manquantes

  • Des zéros à la place des valeurs nulles

Je vous propose donc ici quelques méthodes et packages qui permettent d’effectuer ce nettoyage efficacement.



II) Nettoyage des données avec janitor en R

Parfois, vous devez nettoyer des données dont les colonnes ont des conventions de nommage disons … douteuses. Créons un dataframe chaotique avec des données économiques fictives sur les provinces de Nouvelle-Calédonie, puis nettoyons-les avec le formidable package janitor.

# Installer et charger les packages nécessaires
# install.packages("janitor")
library(janitor)
library(magrittr)  # pour utiliser les pipes (%>%)
library(dplyr)
library(tidyr)


# Créer un jeu de données fictif mal formaté sur les provinces de Nouvelle-Calédonie
data_nc <- data.frame(
  # Nom des provinces
  NomDesProvinces = c("Sud", "Nord", "Îles", "Sud", "Nord"),
  
  # Population en 2023
  population2023 = c(280000, 50000, 18000, 280000, 50000),
  
  # PIB par habitant en dollars
  'PIB (par habitant)' = c(30000, 25000, 20000, 30000, 25000),
  
  # Taux de chômage en %
  tauxChômage2023 = c(6.5, 12.3, 14.7, 6.5, 12.3),
  
  # Une colonne vide comme on en rencontre souvent dans les fichiers Excel
  colonneVide = c(NA, NA, NA, NA, NA)
)

# Afficher les premières lignes
head(data_nc)
  NomDesProvinces population2023 PIB..par.habitant. tauxChômage2023 colonneVide
1             Sud         280000              30000             6.5          NA
2            Nord          50000              25000            12.3          NA
3            Îles          18000              20000            14.7          NA
4             Sud         280000              30000             6.5          NA
5            Nord          50000              25000            12.3          NA

Jettez un coup d’oeil aux noms de colonnes : Hé oui ça pique les yeux !


1. Nettoyer les noms de colonnes

Maintenant, nettoyons donc ces affreux noms de colonnes avec janitor::clean_names() :

# Nettoyer les noms de colonnes
data_nc_clean_names <- data_nc %>%  
  janitor::clean_names() %T>%
  print()
  nom_des_provinces population2023 pib_par_habitant taux_chomage2023
1               Sud         280000            30000              6.5
2              Nord          50000            25000             12.3
3              Îles          18000            20000             14.7
4               Sud         280000            30000              6.5
5              Nord          50000            25000             12.3
  colonne_vide
1           NA
2           NA
3           NA
4           NA
5           NA

Nos colonnes sont désormais lisibles par les humains et les machines. Elles sont également nommées de manière cohérente, avec une convention en minuscules et séparées par des underscores (par exemple snake_case).

Notez qu’obtenir le même résultat sans cette fonction aurait nécessité de nombreuses lignes de code, et aurait favorisé le risque d’erreur !


2. Supprimer les lignes/colonnes vides et les doublons

Utilisons une autre fonction de janitor, remove_empty(), pour supprimer automatiquement les colonnes et les lignes qui sont vides, qui sont choses courantes lorsque l’on importe des fichiers CSV ou Excel.

# Supprimer les lignes et colonnes vides
data_nc_noNA <-data_nc_clean_names %>% 
  janitor::remove_empty(c("rows", "cols")) %T>%
  print()
  nom_des_provinces population2023 pib_par_habitant taux_chomage2023
1               Sud         280000            30000              6.5
2              Nord          50000            25000             12.3
3              Îles          18000            20000             14.7
4               Sud         280000            30000              6.5
5              Nord          50000            25000             12.3

Une autre fonction utile de janitor est get_dupes(). Celle-ci nous alerte sur les lignes en double dans notre jeu de données.

Tout d’abord, dupliquons chaque ligne :

# Dupliquer les lignes pour générer des doublons
data_nc_dupes <- data_nc_noNA %>% 
  dplyr::slice(rep(1:20, each = 2))  

print(data_nc_dupes)
   nom_des_provinces population2023 pib_par_habitant taux_chomage2023
1                Sud         280000            30000              6.5
2                Sud         280000            30000              6.5
3               Nord          50000            25000             12.3
4               Nord          50000            25000             12.3
5               Îles          18000            20000             14.7
6               Îles          18000            20000             14.7
7                Sud         280000            30000              6.5
8                Sud         280000            30000              6.5
9               Nord          50000            25000             12.3
10              Nord          50000            25000             12.3

Ensuite, utilisons get_dupes() pour les trouver :

# Trouver les doublons
janitor::get_dupes(data_nc_dupes)
   nom_des_provinces population2023 pib_par_habitant taux_chomage2023
1               Nord          50000            25000             12.3
2               Nord          50000            25000             12.3
3               Nord          50000            25000             12.3
4               Nord          50000            25000             12.3
5                Sud         280000            30000              6.5
6                Sud         280000            30000              6.5
7                Sud         280000            30000              6.5
8                Sud         280000            30000              6.5
9               Îles          18000            20000             14.7
10              Îles          18000            20000             14.7
   dupe_count
1           4
2           4
3           4
4           4
5           4
6           4
7           4
8           4
9           2
10          2

Enfin, supprimons les doublons avec la fonction que vous connaissez déjà, unique () :

# Conserver uniquement les lignes uniques
data_nc_nodupes <- data_nc_dupes %>% 
  unique() %>% 
  print()
  nom_des_provinces population2023 pib_par_habitant taux_chomage2023
1               Sud         280000            30000              6.5
3              Nord          50000            25000             12.3
5              Îles          18000            20000             14.7


3. Création de tableaux de fréquence et ajout de totaux ou pourcentages avec tabyl et adorn_*

Lorsque vous travaillez avec des données catégorielles, il est souvent utile de créer des tableaux de fréquence ou des tableaux croisés. janitor vous permet d’ajouter facilement des totaux ou des pourcentages. On est moins sur du nettoyage à proprement parler, mais explorer ses données est toujours un bon moyen d’en identifier les limites.

Nous allons utiliser un exemple avec des catégories économiques telles que le secteur d’activité et la répartition par province.

# Exemple de données
data_nc_secteurs <- data.frame(
  secteur = c("Agriculture", "Industrie", "Services", "Industrie", "Agriculture", "Services", "Industrie", "Agriculture"),
  province = c("Sud", "Sud", "Nord", "Îles", "Nord", "Sud", "Îles", "Nord")
)

print(data_nc_secteurs)
      secteur province
1 Agriculture      Sud
2   Industrie      Sud
3    Services     Nord
4   Industrie     Îles
5 Agriculture     Nord
6    Services      Sud
7   Industrie     Îles
8 Agriculture     Nord
# Créer un tableau croisé de fréquence avec tabyl
table_secteur_province <- data_nc_secteurs %>%
  tabyl(secteur, province) %>%
  adorn_totals("row") %>%   # Ajouter les totaux par ligne
  adorn_percentages("row") %>%  # Ajouter les pourcentages par ligne
  adorn_pct_formatting()    # Formater les pourcentages avec le symbole %

Le tableau généré par tabyl() permet de voir la répartition des secteurs économiques entre les provinces. Les totaux par ligne permettent de comprendre la répartition globale, tandis que les pourcentages indiquent la proportion de chaque secteur dans chaque province.

# Afficher le tableau croisé
print(table_secteur_province)
     secteur  Îles  Nord   Sud
 Agriculture  0.0% 66.7% 33.3%
   Industrie 66.7%  0.0% 33.3%
    Services  0.0% 50.0% 50.0%
       Total 25.0% 37.5% 37.5%

Ce tableau montre par exemple que le secteur agricole est réparti entre les provinces Nord et Sud, tandis que le secteur industriel est principalement concentré dans la province des Îles (hé oui ce sont des données fictives je fais ce que je veux!).



III) Données “Tidy” vs. “Non-Tidy”

Dans une analyse de données efficace, il est crucial de travailler avec des données au format “tidy”. Les données tidy suivent un principe simple : chaque variable forme une colonne, chaque observation forme une ligne, et chaque valeur forme une cellule. Cependant, il est courant de recevoir des données dans un format “non-tidy”, ce qui peut compliquer les analyses.

Dans cette section, nous allons explorer un exemple de données “non-tidy”, examiner pourquoi cela pose problème, puis transformer ces données en un format “tidy”.


1. Exemple de données “Non-Tidy”

Imaginons que l’ISEE a mené une enquête sur les individus dans plusieurs communes de Nouvelle-Calédonie. Les données sont enregistrées sous forme de colonnes multiples représentant les revenus par année, plutôt que d’avoir une colonne unique pour les revenus et une colonne pour les années. Voici à quoi pourraient ressembler ces données :

# Créer un jeu de données non-tidy d'individus enquêtés par l'ISEE
data_non_tidy <- data.frame(
  individu = c("Indiv1", "Indiv2", "Indiv3", "Indiv4"),
  commune = c("Nouméa", "Dumbéa", "Mont-Dore", "Bourail"),
  revenu_2019 = c(25000, 30000, 27000, 26000),
  revenu_2020 = c(26000, 31000, 28000, 26500),
  revenu_2021 = c(27000, 32000, 29000, 27000)
)

# Afficher les données
print(data_non_tidy)
  individu   commune revenu_2019 revenu_2020 revenu_2021
1   Indiv1    Nouméa       25000       26000       27000
2   Indiv2    Dumbéa       30000       31000       32000
3   Indiv3 Mont-Dore       27000       28000       29000
4   Indiv4   Bourail       26000       26500       27000

Voici à quoi ressemblent ces données “non-tidy” :

individu commune revenu_2019 revenu_2020 revenu_2021
Indiv1 Nouméa 25000 26000 27000
Indiv2 Dumbéa 30000 31000 32000
Indiv3 Mont-Dore 27000 28000 29000
Indiv4 Bourail 26000 26500 27000


2. Pourquoi ces données posent problème

Le format “non-tidy” crée plusieurs difficultés :

  • Incohérence : Chaque variable (le revenu) est répartie sur plusieurs colonnes. Cela devient problématique si on doit ajouter de nouvelles années ou traiter les revenus de manière systématique (par exemple, calculer l’augmentation annuelle).

  • Complexité de manipulation : Les fonctions de manipulation de données (par exemple dplyr) et de visualisation (par exemple ggplot2) sont conçues pour fonctionner avec des données tidy. Manipuler des données non-tidy demande plus de code et entraîne un risque d’erreurs.

  • Difficulté de généralisation : Si on ajoute une année supplémentaire, il faut créer une nouvelle colonne et réajuster tout le code d’analyse, alors qu’une structure tidy permet de traiter les données plus dynamiquement.


3. Transformation vers un format “Tidy”

Nous allons maintenant utiliser la fonction pivot_longer() de tidyr pour transformer ces données en un format tidy.

# Transformer les données vers un format tidy
data_tidy <- data_non_tidy %>%
  pivot_longer(cols = starts_with("revenu_"),
               names_to = "année",
               values_to = "revenu")

# Afficher les données tidy
print(data_tidy)
# A tibble: 12 × 4
   individu commune   année       revenu
   <chr>    <chr>     <chr>        <dbl>
 1 Indiv1   Nouméa    revenu_2019  25000
 2 Indiv1   Nouméa    revenu_2020  26000
 3 Indiv1   Nouméa    revenu_2021  27000
 4 Indiv2   Dumbéa    revenu_2019  30000
 5 Indiv2   Dumbéa    revenu_2020  31000
 6 Indiv2   Dumbéa    revenu_2021  32000
 7 Indiv3   Mont-Dore revenu_2019  27000
 8 Indiv3   Mont-Dore revenu_2020  28000
 9 Indiv3   Mont-Dore revenu_2021  29000
10 Indiv4   Bourail   revenu_2019  26000
11 Indiv4   Bourail   revenu_2020  26500
12 Indiv4   Bourail   revenu_2021  27000

Les données tidy se présentent ainsi :

individu commune année revenu
Indiv1 Nouméa revenu_2019 25000
Indiv1 Nouméa revenu_2020 26000
Indiv1 Nouméa revenu_2021 27000
Indiv2 Dumbéa revenu_2019 30000
Indiv2 Dumbéa revenu_2020 31000
Indiv2 Dumbéa revenu_2021 32000
Indiv3 Mont-Dore revenu_2019 27000
Indiv3 Mont-Dore revenu_2020 28000
Indiv3 Mont-Dore revenu_2021 29000
Indiv4 Bourail revenu_2019 26000
Indiv4 Bourail revenu_2020 26500
Indiv4 Bourail revenu_2021 27000

Avantages du Format Tidy

  1. Facilité de Manipulation : Les données tidy sont cohérentes avec les fonctions de manipulation des packages comme dplyr et ggplot2. Cela permet d’écrire des scripts plus clairs et plus efficaces.

  2. Flexibilité : Ajouter de nouvelles années ou variables devient plus simple car le format de données reste constant.

  3. Clarté et Standardisation : Les données tidy sont plus intuitives et respectent les standards reconnus pour l’analyse de données, facilitant ainsi la collaboration et la réutilisation du code.

Conclusion : UTILISEZ DES DONNEES TIDY !! .



IV) Changer la forme des données avec gather() et spread()

Dans l’analyse de données, nous avons souvent besoin de transformer des jeux de données d’un format large (où les observations sont réparties sur plusieurs colonnes) à un format long (où chaque observation est sur une ligne séparée). Ces transformations permettent d’adapter les données aux analyses souhaitées, surtout lorsqu’il s’agit de visualisations ou de calculs spécifiques.


1. Exemple de données économiques Non-Tidy

Imaginons que l’ISEE a collecté des données sur l’emploi dans différentes communes de Nouvelle-Calédonie au fil des ans, avec les effectifs dans chaque secteur (agriculture, industrie, services). Voici à quoi pourrait ressembler ce jeu de données en format large :

# Création d'un jeu de données non-tidy sur l'emploi par secteur et année
emploi_df <- data.frame(
  commune = c("Nouméa", "Dumbéa", "Mont-Dore", "Bourail"),
  annee_2019_agriculture = c(120, 80, 90, 60),
  annee_2019_industrie = c(300, 150, 120, 70),
  annee_2019_services = c(500, 400, 350, 100),
  annee_2020_agriculture = c(125, 85, 95, 65),
  annee_2020_industrie = c(310, 155, 130, 75),
  annee_2020_services = c(510, 410, 360, 105)
)

print(emploi_df)
    commune annee_2019_agriculture annee_2019_industrie annee_2019_services
1    Nouméa                    120                  300                 500
2    Dumbéa                     80                  150                 400
3 Mont-Dore                     90                  120                 350
4   Bourail                     60                   70                 100
  annee_2020_agriculture annee_2020_industrie annee_2020_services
1                    125                  310                 510
2                     85                  155                 410
3                     95                  130                 360
4                     65                   75                 105

Le jeu de données est au format large et ressemble à ceci :

commune annee_2019_agriculture annee_2019_industrie annee_2019_services annee_2020_agriculture annee_2020_industrie annee_2020_services
Nouméa 120 300 500 125 310 510
Dumbéa 80 150 400 85 155 410
Mont-Dore 90 120 350 95 130 360
Bourail 60 70 100 65 75 105


2. Problèmes posés par ce format Non-Tidy

Le format large présente plusieurs inconvénients :

  • Complexité d’analyse : Il est difficile d’effectuer des opérations d’agrégation ou de comparaison car chaque combinaison d’année et de secteur est dans une colonne distincte.

  • Difficulté de visualisation : La création de graphiques sera compliquée car les données sont éparpillées sur plusieurs colonnes.

  • Ajout de nouvelles données : Ajouter une nouvelle année nécessitera la création de nouvelles colonnes, rendant le jeu de données encore plus large.

Pour résoudre ces problèmes, nous devons passer à un format long où chaque ligne représente une observation unique.


3. Transformation des données avec gather()

Nous allons maintenant utiliser gather() pour transformer ces données en format long, en regroupant les colonnes correspondant aux différentes années et secteurs sous des colonnes communes.

# Transformation des données vers un format long (tidy)
emploi_tidy <- emploi_df %>%
  gather(key = "annee_secteur", value = "effectifs", -commune)

# Afficher les premières lignes du jeu de données tidy
head(emploi_tidy)
    commune          annee_secteur effectifs
1    Nouméa annee_2019_agriculture       120
2    Dumbéa annee_2019_agriculture        80
3 Mont-Dore annee_2019_agriculture        90
4   Bourail annee_2019_agriculture        60
5    Nouméa   annee_2019_industrie       300
6    Dumbéa   annee_2019_industrie       150

Le jeu de données transformé en format tidy :

commune annee_secteur effectifs
Nouméa annee_2019_agriculture 120
Nouméa annee_2019_industrie 300
Nouméa annee_2019_services 500
Nouméa annee_2020_agriculture 125
Nouméa annee_2020_industrie 310
Nouméa annee_2020_services 510

Nous avons maintenant une colonne “annee_secteur” qui regroupe les informations sur les années et les secteurs, et une colonne “effectifs” qui contient les effectifs correspondants.


4. Séparation des Colonnes annee et secteur

Afin de simplifier l’analyse, il est utile de séparer la colonne “annee_secteur” en deux colonnes distinctes : “annee” et “secteur”.

# Séparer la colonne annee_secteur en deux colonnes distinctes
emploi_tidy_sep <- emploi_tidy %>%
  separate(col = annee_secteur, into = c("a_jeter", "annee", "secteur"), sep = "_", extra = "merge") %>% 
  select(., - a_jeter)

# Afficher le jeu de données final
head(emploi_tidy_sep)
    commune annee     secteur effectifs
1    Nouméa  2019 agriculture       120
2    Dumbéa  2019 agriculture        80
3 Mont-Dore  2019 agriculture        90
4   Bourail  2019 agriculture        60
5    Nouméa  2019   industrie       300
6    Dumbéa  2019   industrie       150

Le jeu de données final au format tidy ressemble à ceci :

commune annee secteur effectifs
Nouméa 2019 agriculture 120
Nouméa 2019 industrie 300
Nouméa 2019 services 500
Nouméa 2020 agriculture 125
Nouméa 2020 industrie 310
Nouméa 2020 services 510


5. Revenir à un format large avec spread()

Si pour une raison ou une autre nous avons besoin de revenir à un format large, nous pouvons utiliser spread().

# Transformer les données en format large avec spread()
emploi_large <- emploi_tidy_sep %>%
  spread(key = secteur, value = effectifs)

# Afficher les premières lignes du jeu de données large
head(emploi_large)
    commune annee agriculture industrie services
1   Bourail  2019          60        70      100
2   Bourail  2020          65        75      105
3    Dumbéa  2019          80       150      400
4    Dumbéa  2020          85       155      410
5 Mont-Dore  2019          90       120      350
6 Mont-Dore  2020          95       130      360

Le jeu de données redevient large, avec une colonne par secteur et une ligne par commune et année :

commune annee agriculture industrie services
Bourail 2019 60 70 100
Bourail 2020 65 75 105
Dumbéa 2019 80 150 400
Dumbéa 2020 85 155 410
Mont-Dore 2019 90 120 350
Mont-Dore 2020 95 130 360


6. Conclusion

Travailler avec des données tidy permet de simplifier les manipulations, les analyses et les visualisations. Les fonctions gather() et spread() (remplacées par pivot_longer() et pivot_wider() dans les versions récentes de tidyr) sont des outils essentiels pour structurer les données selon les besoins analytiques.



V) Recherche et remplacement de patterns avec les Regex

Dans le processus de nettoyage des données, une étape essentielle est la recherche et le remplacement de certains motifs ou patterns. Les données sont souvent sujettes à des incohérences de format, telles que des espaces supplémentaires, des caractères spéciaux indésirables, ou des formats d’entrées incorrects. Pour résoudre ces problèmes, gsub() et les expressions régulières (regex) sont des outils puissants en R.

Les regex (expressions régulières) sont des modèles de recherche qui permettent de repérer des chaînes de caractères complexes. Bien qu’elles puissent sembler intimidantes au début, elles sont incroyablement efficaces pour repérer des motifs spécifiques dans vos données et les remplacer en une seule commande.


1. Exemple de jeu de données

Imaginons que nous avons un jeu de données collecté par l’ISEE, où certaines informations ont été mal saisies. Nous allons créer un exemple de ce type de jeu de données, et ensuite corriger ces incohérences de format.

# Jeu de données avec incohérences de format
data_isee <- data.frame(
  Nom = c(" DUPONT", "Martin", "lAMIRAL  ", "MARTIN", " Duval", "BOUCHER", "dupont"),
  Age = c("25", " 30", " 25 ", "Trente-Cinq", "33 ans", "40", "25"),
  Sexe = c("M", "F ", "M", "F", "F", "M", "H"),
  Ville = c("Noumea", "NOU MÉA", "Nouméa", "NOUMEA", "   DUMBEA", "Dumbea", "DUMBEA"),
  Date_Enquête = c("12/06/2021", "06-07-21", "2021-06-08", "08/06/21", "08 Juin 2021", "10 Juin 21", "10/06/2021")
)

print(data_isee)
        Nom         Age Sexe     Ville Date_Enquête
1    DUPONT          25    M    Noumea   12/06/2021
2    Martin          30   F    NOU MÉA     06-07-21
3 lAMIRAL           25     M    Nouméa   2021-06-08
4    MARTIN Trente-Cinq    F    NOUMEA     08/06/21
5     Duval      33 ans    F    DUMBEA 08 Juin 2021
6   BOUCHER          40    M    Dumbea   10 Juin 21
7    dupont          25    H    DUMBEA   10/06/2021

Ce jeu de données présente plusieurs incohérences :

  • Espaces blancs au début ou à la fin des noms et des âges.

  • Incohérences dans les formats des âges (“25”, “Trente-Cinq”, “33 ans”).

  • Problèmes de formatage des villes, avec des majuscules ou des accents manquants.

  • Formats de date incohérents (“12/06/2021”, “06-07-21”, “08 Juin 2021”).


2. Utilisation de gsub() et des regex pour corriger les incohérences

Nettoyage des Noms et des Âges

Nous allons d’abord retirer les espaces inutiles dans les noms et les âges, et corriger les âges non numériques.

# Nettoyage des espaces autour des noms et âges
data_isee$Nom <- gsub("^\\s+|\\s+$", "", data_isee$Nom)  # Enlever les espaces au début et à la fin
data_isee$Age <- gsub("^\\s+|\\s+$", "", data_isee$Age)  # Même opération pour les âges

# Remplacer les âges en texte par des chiffres
data_isee$Age <- gsub("Trente-Cinq", "35", data_isee$Age)
data_isee$Age <- gsub("ans", "", data_isee$Age)
data_isee$Age <- as.numeric(data_isee$Age)

print(data_isee)
      Nom Age Sexe     Ville Date_Enquête
1  DUPONT  25    M    Noumea   12/06/2021
2  Martin  30   F    NOU MÉA     06-07-21
3 lAMIRAL  25    M    Nouméa   2021-06-08
4  MARTIN  35    F    NOUMEA     08/06/21
5   Duval  33    F    DUMBEA 08 Juin 2021
6 BOUCHER  40    M    Dumbea   10 Juin 21
7  dupont  25    H    DUMBEA   10/06/2021

Pas mal non ?
Je vous entend d’ici et je vous comprend : C’est quoi ça "^\\s+|\\s+$" ???

Prenons un moment pour l’expliquer simplement, puis nous allons aborder ce qu’est une expression régulière (regex) et comment l’utiliser.


3. Qu’est-ce qu’une Regex ?

Une expression régulière, ou regex, est un “motif” que l’on utilise pour chercher des séquences spécifiques de caractères dans un texte. Pensez à une regex comme une sorte de détecteur de modèles : elle permet de trouver, de remplacer, ou de manipuler du texte qui correspond à ce motif.

Comment utiliser une Regex ?

En général, les regex sont utilisées pour des tâches comme :

  • Rechercher : Trouver un mot ou un modèle dans un texte.

  • Remplacer : Modifier des parties du texte qui correspondent au motif.

  • Vérifier : Vérifier si un texte correspond à un modèle spécifique (par exemple, si un email est valide).

Explication de ^\\s+|\\s+$

Voyons cette expression régulière étape par étape, avec un exemple simple.

  1. ^ : Ce symbole indique le début du texte. Donc, tout ce qui suit va être recherché au début de la chaîne de caractères.

  2. \\s+ : \\s signifie espace blanc (cela peut être un espace, une tabulation, etc.). Le + signifie “un ou plusieurs” espaces.

  3. | : C’est un “OU”. Cela signifie que nous cherchons soit ce qu’il y a avant, soit ce qu’il y a après ce symbole.

  4. \\s+$ : \\s+ signifie encore un ou plusieurs espaces blancs, mais cette fois le $ signifie la fin du texte.

Pas besoin d’apprendre par coeur : ChatGPT sait très bien les faire, il suffit de lui demander !

En résumé, que fait ^\\s+|\\s+$ ?

Cette regex sert à trouver les espaces en trop au début et à la fin d’un texte. Par exemple, si vous avez la chaîne " Bonjour ", elle détectera les espaces avant et après "Bonjour".

Comment l’utiliser en pratique ?

Imaginons que vous souhaitiez supprimer les espaces au début et à la fin d’une chaîne de caractères. Voici un exemple en R :

# Exemple de chaîne de caractères avec des espaces en trop
texte <- "   Bonjour le monde   "

# Utilisation de gsub pour enlever les espaces au début et à la fin
texte_sans_espaces <- gsub("^\\s+|\\s+$", "", texte)

# Affichage du résultat
print(texte_sans_espaces)  # Résultat : "Bonjour le monde"
[1] "Bonjour le monde"


4. gsub() & Regex (suite)

Uniformisation des noms de villes

Ensuite, nous harmonisons les noms des villes en utilisant des regex pour uniformiser la casse et les accents.

# Mise en forme des noms de villes
data_isee$Ville <- gsub("\\s+", "", data_isee$Ville)  # Enlever les espaces inutiles
data_isee$Ville <- tolower(data_isee$Ville)  # Tout en minuscules
data_isee$Ville <- gsub("nouméa|noumea", "Nouméa", data_isee$Ville)  # Uniformiser les noms
data_isee$Ville <- gsub("dumbea|dumbéa", "Dumbéa", data_isee$Ville)  # Même opération pour Dumbéa

print(data_isee)
      Nom Age Sexe  Ville Date_Enquête
1  DUPONT  25    M Nouméa   12/06/2021
2  Martin  30   F  Nouméa     06-07-21
3 lAMIRAL  25    M Nouméa   2021-06-08
4  MARTIN  35    F Nouméa     08/06/21
5   Duval  33    F Dumbéa 08 Juin 2021
6 BOUCHER  40    M Dumbéa   10 Juin 21
7  dupont  25    H Dumbéa   10/06/2021

Correction des formats de date

Enfin, nous harmonisons les formats de date pour qu’ils suivent tous le même modèle.

# Uniformisation des formats de date
data_isee$Date_Enquête <- gsub(" ", "-", data_isee$Date_Enquête)  # Remplacer les espaces par des tirets
data_isee$Date_Enquête <- gsub("/", "-", data_isee$Date_Enquête)  # Remplacer les slashes par des tirets
data_isee$Date_Enquête <- gsub("Juin", "06", data_isee$Date_Enquête)  # Remplacer les mois en lettres par des numéros de mois

print(data_isee)
      Nom Age Sexe  Ville Date_Enquête
1  DUPONT  25    M Nouméa   12-06-2021
2  Martin  30   F  Nouméa     06-07-21
3 lAMIRAL  25    M Nouméa   2021-06-08
4  MARTIN  35    F Nouméa     08-06-21
5   Duval  33    F Dumbéa   08-06-2021
6 BOUCHER  40    M Dumbéa     10-06-21
7  dupont  25    H Dumbéa   10-06-2021

Hey vous avez vu, la date de la ligne N°3 est au mauvais format, il va falloir détecter les cas comme celui-ci et les corriger en “renversant” la date :

# Définir une fonction pour identifier si une date est au mauvais format
is_misformatted <- function(date_string) {
  grepl("^\\d{4}-\\d{2}-\\d{2}$", date_string) # Détecte le format ISO (YYYY-MM-DD)
}

# Appliquer la transformation conditionnelle pour renverser les dates mal formatées
data_isee_bonnes_dates <- data_isee %>%
  mutate(Date_Enquête = ifelse(is_misformatted(Date_Enquête),
                           format(as.Date(Date_Enquête, format = "%Y-%m-%d"), "%d-%m-%Y"), Date_Enquête))

On convertit le tout en date ci dessous et … ça passe !

# Convertir les dates en format Date standard
data_isee_bonnes_dates$Date_Enquête <- as.Date(data_isee_bonnes_dates$Date_Enquête, format = "%d-%m-%Y")

print(data_isee_bonnes_dates)
      Nom Age Sexe  Ville Date_Enquête
1  DUPONT  25    M Nouméa   2021-06-12
2  Martin  30   F  Nouméa   0021-07-06
3 lAMIRAL  25    M Nouméa   2021-06-08
4  MARTIN  35    F Nouméa   0021-06-08
5   Duval  33    F Dumbéa   2021-06-08
6 BOUCHER  40    M Dumbéa   0021-06-10
7  dupont  25    H Dumbéa   2021-06-10


5. Conclusion

Grâce à l’utilisation de gsub() et des expressions régulières, nous avons corrigé plusieurs incohérences courantes dans nos données :

  • Nous avons enlevé les espaces blancs inutiles.

  • Nous avons uniformisé les formats de texte (comme les noms de villes).

  • Nous avons standardisé les dates.

Les regex sont un outil puissant et flexible pour repérer et corriger les motifs récurrents dans vos données. Grâce à leur utilisation, vous pouvez rendre vos jeux de données plus propres et plus faciles à analyser.



Sources

Je me suis inspiré des sources suivantes pour ce tutoriel, le crédit leur revient donc tout naturellement !