35 Chaînes de texte avec stringr
Les fonctions de forcats vues précédemment permettent de modifier des modalités d’une variables qualitative globalement. Mais parfois on a besoin de manipuler le contenu même du texte d’une variable de type chaîne de caractères : combiner, rechercher, remplacer…
On va utiliser ici les fonctions de l’extension stringr. Celle-ci fait partie du cœur du tidyverse, elle est donc automatiquement chargée avec :
Dans ce qui suit on va utiliser le court tableau d’exemple d
suivant :
nom | adresse | ville |
---|---|---|
Mr Félicien Machin | 3 rue des Fleurs | Nouméa |
Mme Raymonde Bidule | 47 ave de la Libération | Marseille |
M. Martial Truc | 12 rue du 17 octobre 1961 | Vénissieux |
Mme Huguette Chose | 221 avenue de la Libération | Marseille |
35.1 Concaténer des chaînes
La première opération de base consiste à concaténer des chaînes de caractères entre elles. On peut le faire avec la fonction paste()
.
Par exemple, si on veut concaténer l’adresse et la ville :
[1] "3 rue des Fleurs Nouméa"
[2] "47 ave de la Libération Marseille"
[3] "12 rue du 17 octobre 1961 Vénissieux"
[4] "221 avenue de la Libération Marseille"
Par défaut, paste()
concatène en ajoutant un espace entre les différentes chaînes. On peut spécifier un autre séparateur avec son argument sep
:
[1] "3 rue des Fleurs - Nouméa"
[2] "47 ave de la Libération - Marseille"
[3] "12 rue du 17 octobre 1961 - Vénissieux"
[4] "221 avenue de la Libération - Marseille"
Il existe une variante, paste0()
, qui concatène sans mettre de séparateur, et qui est légèrement plus rapide :
[1] "3 rue des FleursNouméa"
[2] "47 ave de la LibérationMarseille"
[3] "12 rue du 17 octobre 1961Vénissieux"
[4] "221 avenue de la LibérationMarseille"
À noter que paste()
et paste0()
sont des fonctions R de base. L’équivalent pour stringr se nomme stringr::str_c()
.
Parfois on cherche à concaténer les différents éléments d’un vecteur non pas avec ceux d’un autre vecteur, comme on l’a fait précédemment, mais entre eux. Dans ce cas paste()
seule ne fera rien :
Il faut lui ajouter un argument collapse
, avec comme valeur la chaîne à utiliser pour concaténer les éléments :
35.2 Convertir en majuscules / minuscules
Les fonctions stringr::str_to_lower()
, stringr::str_to_upper()
et stringr::str_to_title()
permettent respectivement de mettre en minuscules, mettre en majuscules, ou de capitaliser les éléments d’un vecteur de chaînes de caractères :
[1] "mr félicien machin" "mme raymonde bidule" "m. martial truc"
[4] "mme huguette chose"
[1] "MR FÉLICIEN MACHIN" "MME RAYMONDE BIDULE" "M. MARTIAL TRUC"
[4] "MME HUGUETTE CHOSE"
35.3 Découper des chaînes
La fonction stringr::str_split()
permet de “découper” une chaîne de caractère en fonction d’un délimiteur. On passe la chaîne en premier argument, et le délimiteur en second :
On peut appliquer la fonction à un vecteur, dans ce cas le résultat sera une liste :
[[1]]
[1] "Mr" "Félicien" "Machin"
[[2]]
[1] "Mme" "Raymonde" "Bidule"
[[3]]
[1] "M." "Martial" "Truc"
[[4]]
[1] "Mme" "Huguette" "Chose"
Ou un tableau (plus précisément une matrice) si on ajoute simplify = TRUE
.
[,1] [,2] [,3]
[1,] "Mr" "Félicien" "Machin"
[2,] "Mme" "Raymonde" "Bidule"
[3,] "M." "Martial" "Truc"
[4,] "Mme" "Huguette" "Chose"
Si on souhaite créer de nouvelles colonnes dans un tableau de données en découpant une colonne de type texte, on pourra utiliser la fonction tidyr::separate()
de l’extension tidyr (cf. Section 36.5).
Voici juste un exemple de son utilisation :
Warning: Expected 3 pieces. Additional pieces discarded in 1 rows [1].
# A tibble: 4 × 5
genre prenom nom adresse ville
<chr> <chr> <chr> <chr> <chr>
1 Mr F licien 3 rue des Fleurs Nouméa
2 Mme Raymonde Bidule 47 ave de la Libération Marseille
3 M Martial Truc 12 rue du 17 octobre 1961 Vénissieux
4 Mme Huguette Chose 221 avenue de la Libération Marseille
35.4 Extraire des sous-chaînes par position
La fonction stringr::str_sub()
permet d’extraire des sous-chaînes par position, en indiquant simplement les positions des premier et dernier caractères :
35.5 Détecter des motifs
stringr::str_detect()
permet de détecter la présence d’un motif parmi les éléments d’un vecteur. Par exemple, si on souhaite identifier toutes les adresses contenant Libération
:
stringr::str_detect()
renvoi un vecteur de valeurs logiques et peut donc être utilisée, par exemple, avec le verbe dplyr::filter()
pour extraire des sous-populations.
# A tibble: 2 × 3
nom adresse ville
<chr> <chr> <chr>
1 Mme Raymonde Bidule 47 ave de la Libération Marseille
2 Mme Huguette Chose 221 avenue de la Libération Marseille
Une variante, stringr::str_count()
, compte le nombre d’occurrences d’une chaîne pour chaque élément d’un vecteur :
Attention, les fonctions de stringr étant prévues pour fonctionner avec des expressions régulières, certains caractères n’auront pas le sens habituel dans la chaîne indiquant le motif à rechercher. Par exemple, le .
ne sera pas un point mais le symbole représentant n’importe quel caractère
.
La section sur les modificateurs de motifs explique comment utiliser des chaîne classiques
au lieu d’expressions régulières.
On peut aussi utiliser stringr::str_subset()
pour ne garder d’un vecteur que les éléments correspondant au motif :
35.6 Expressions régulières
Les fonctions présentées ici sont pour la plupart prévues pour fonctionner avec des expressions régulières. Celles-ci constituent un mini-langage, qui peut paraître assez cryptique, mais qui est très puissant pour spécifier des motifs de chaînes de caractères.
Elles permettent par exemple de sélectionner le dernier mot avant la fin d’une chaîne, l’ensemble des suites alphanumériques commençant par une majuscule, des nombres de 3 ou 4 chiffres situés en début de chaîne, et beaucoup beaucoup d’autres choses encore bien plus complexes.
Pour donner un exemple concret, l’expression régulière suivante permet de détecter une adresse de courrier électronique1 :
1 Il s’agit en fait d’une version très simplifiée, la véritable
expression permettant de tester si une adresse mail est valide fait plus de 80 lignes…
[\w\d+.-_]+@[\w\d.-]+\.[a-zA-Z]{2,}
Les exemples donnés dans ce chapitre ont utilisés autant que possible de simples chaînes de texte, sans expression régulière. Mais si vous pensez manipuler des données textuelles, il peut être très utile de s’intéresser à cette syntaxe.
35.7 Extraire des motifs
stringr::str_extract()
permet d’extraire les valeurs correspondant à un motif. Si on lui passe comme motif une chaîne de caractère, cela aura peu d’intérêt :
C’est tout de suite plus intéressant si on utilise des expressions régulières. Par exemple la commande suivante permet d’isoler les numéros de rue.
stringr::str_extract()
ne récupère que la première occurrence du motif. Si on veut toutes les extraire on peut utiliser stringr::str_extract_all()
. Ainsi, si on veut extraire l’ensemble des nombres présents dans les adresses :
[[1]]
[1] "3"
[[2]]
[1] "47"
[[3]]
[1] "12" "17" "1961"
[[4]]
[1] "221"
Si on veut faire de l’extraction de groupes dans des expressions régulières (identifiés avec des parenthèses), on pourra utiliser str_match
.
À noter que si on souhaite extraire des valeurs d’une colonne texte d’un tableau de données pour créer de nouvelles variables, on pourra plutôt utiliser la fonction tidyr::extract()
de l’extension tidyr (cf. Section 36.8).
Par exemple :
# A tibble: 4 × 4
nom adresse type_rue ville
<chr> <chr> <chr> <chr>
1 Mr Félicien Machin 3 rue des Fleurs rue Nouméa
2 Mme Raymonde Bidule 47 ave de la Libération ave Marseille
3 M. Martial Truc 12 rue du 17 octobre 1961 rue Vénissieux
4 Mme Huguette Chose 221 avenue de la Libération avenue Marseille
35.8 Remplacer des motifs
La fonction stringr::str_replace()
permet de remplacer une chaîne ou un motif par une autre.
Par exemple, on peut remplace les occurrence de “Mr” par “M.” dans les noms de notre tableau :
[1] "M. Félicien Machin" "Mme Raymonde Bidule" "M. Martial Truc"
[4] "Mme Huguette Chose"
La variante stringr::str_replace_all()
permet de spécifier plusieurs remplacements d’un coup :
35.9 Modificateurs de motifs
Par défaut, les motifs passés aux fonctions comme stringr::str_detect()
, stringr::str_extract()
ou stringr::str_replace()
sont des expressions régulières classiques.
On peut spécifier qu’un motif n’est pas une expression régulière mais une chaîne de caractères normale en lui appliquant la fonction stringr::fixed()
. Par exemple, si on veut compter le nombre de points dans les noms de notre tableau, le paramétrage par défaut ne fonctionnera pas car dans une expression régulière le .
est un symbole signifiant n’importe quel caractère
:
Il faut donc spécifier que notre point est bien un point avec stringr::fixed()
:
On peut aussi modifier le comportement des expressions régulières à l’aide de la fonction stringr::regex()
. On peut ainsi rendre les motifs insensibles à la casse avec ignore_case
:
On peut également permettre aux expressions régulières d’être multilignes avec l’option multiline = TRUE
, etc.
35.10 Insérer une variable dans une chaîne de caractères
La fonction stringr::str_glue()
repose sur l’extension glue. Elle permet, à l’aide d’une syntaxe un peu spécifique, de pouvoir insérer facilement les valeurs d’une ou plusieurs variables dans une chaîne de caractères. Prenons un exemple :
prenom <- "Fred"
age <- 28
anniversaire <- as.Date("1991-10-12")
str_glue(
"Je m'appelle {prenom}. ",
"L'année prochaine j'aurai {age + 1} ans, ",
"car je suis né le {format(anniversaire, '%A %d %B %Y')}."
)
Je m'appelle Fred. L'année prochaine j'aurai 29 ans, car je suis né le samedi 12 octobre 1991.
Sa variante stringr::str_glue_data()
est adaptée lorsque l’on travaille sur un tableau de données.
35.11 Ressources
L’ouvrage R for Data Science, accessible en ligne, contient un chapitre entier sur les chaînes de caractères et les expressions régulières (en anglais).
Le site officiel de stringr contient une liste des fonctions et les pages d’aide associées, ainsi qu’un article dédié aux expressions régulières.
Pour des besoins plus pointus, on pourra aussi utiliser le package stringi sur lequel est basé stringr.