Considérons l'ensemble de données reproductible suivant, que j'ai créé sur la base de l'ensemble de données Donald Trump-Tweets (que l'on peut trouver à l'adresse suivante aquí ):
df <- tibble(target = c(rep("jeb-bush", 2), rep("jeb-bush-supporters", 2),
"jeb-staffer", rep("the-media", 5)),
tweet_id = seq(1, 10, 1))
Il se compose de deux colonnes, le groupe cible des tweets et le tweet_id :
# A tibble: 10 x 2
target tweet_id
<chr> <dbl>
1 jeb-bush 1
2 jeb-bush 2
3 jeb-bush-supporters 3
4 jeb-bush-supporters 4
5 jeb-staffer 5
6 the-media 6
7 the-media 7
8 the-media 8
9 the-media 9
10 the-media 10
Objectif :
Chaque fois qu'un élément dans target
commence par jeb
je veux extraire la chaîne de caractères après le motif -
. Et quand il y a plusieurs -
dans un élément qui commence par jeb
je veux extraire la chaîne de caractères après le DERNIER -
(ce qui, dans cet exemple d'ensemble de données, ne serait que le cas pour jeb-bush-supporters
). Pour chaque élément qui ne commence pas par jeb
Je veux juste créer la chaîne other
. Au final, cela devrait ressembler à ceci :
# A tibble: 10 x 3
target tweet_id new_var
<chr> <dbl> <chr>
1 jeb-bush 1 bush
2 jeb-bush 2 bush
3 jeb-bush-supporters 3 supporters
4 jeb-bush-supporters 4 supporters
5 jeb-staffer 5 staffer
6 the-media 6 other
7 the-media 7 other
8 the-media 8 other
9 the-media 9 other
10 the-media 10 other
Ce que j'ai essayé :
J'ai réussi à créer le résultat souhaité avec le code suivant :
df %>%
mutate(new_var = case_when(str_detect(target, "^jeb-[a-z]+$") ~
str_extract(target, "(?<=[a-z]{3}-)[a-z]+"),
str_detect(target, "^jeb-[a-z]+-[a-z]+") ~
str_extract(target, "(?<=[a-z]{3}-[a-z]{4}-)[a-z]+"),
TRUE ~ "other"))
Mais le problème est le suivant :
Dans le deuxième str_extract
je dois définir le nombre exact de lettres dans la déclaration "Positive Look Behind" ( [a-z]{4}
). Sinon, R se plaint d'avoir besoin d'une "longueur maximale bornée". Mais que faire si je ne connais pas la longueur exacte du motif ou si elle varie d'un élément à l'autre ?
Par ailleurs, j'ai essayé de travailler avec des groupes de capture plutôt qu'avec des "Look Arounds". J'ai donc essayé d'inclure str_match
pour définir ce que je veux extraire au lieu de ce que je ne veux pas extraire :
df %>%
mutate(new_var = case_when(str_detect(target, "^jeb-[a-z]+$") ~
str_match(target, "jeb-([a-z]+)"),
str_detect(target, "^jeb-[a-z]+-[a-z]+") ~
str_match(target, "jeb-[a-z]+-([a-z]+)"),
TRUE ~ "other"))
Mais ensuite, je reçois ce message d'erreur :
Error: Problem with `mutate()` input `new_var`.
x `str_detect(target, "^jeb-[a-z]+$") ~ str_match(target, "jeb-([a-z]+)")`, `str_detect(target, "^jeb-[a-z]+-[a-z]+") ~ str_match(target,
"jeb-[a-z]{4}-([a-z]+)")` must be length 10 or one, not 20.
i Input `new_var` is `case_when(...)`.
Question :
En fin de compte, je veux savoir s'il existe un moyen concis d'extraire des modèles de chaîne spécifiques dans une déclaration case_when. Comment pourrais-je contourner le problème que j'ai énoncé ici, lorsque je ne serais pas en mesure d'utiliser les "Look Arounds" (parce que je ne peux pas définir une longueur maximale limitée) ni les groupes de capture (parce que str_match
retournerait un vecteur de longueur 20 et non de la taille originale 10 ou un) ?