2017-05-09 4 views
3

J'essaie de faire une substitution de chaîne de données dans R. Je dois trouver tous les mots précédés de '@' (sans espace, par exemple @word) et changer le '@ ' pour '!' (par exemple de @word to! word). En même temps, il laisse intacts les autres instances de '@' (par exemple @ ou @@ ou @ [@]). Par exemple, voici mon dataframe d'origine (pour changer: @def, @jkl, @stu):Substituer mot par le même mot sans initiale @ dans R

> df = data.frame(number = 1:4, text = c('abc @def ghi', '@jkl @ mno', '@[@] pqr @stu', 'vwx @@@ yz')) 
> df 
    number   text 
1  1 abc @def ghi 
2  2 @jkl @ mno 
3  3 @[@] pqr @stu 
4  4 vwx @@@ yz 

Et ce que je besoin pour ressembler à:

> df_result = data.frame(number = 1:4, text = c('abc !def ghi', '!jkl @ mno', '@[@] pqr !stu', 'vwx @@@ yz')) 
> df_result 
    number   text 
1  1 abc !def ghi 
2  2 !jkl @ mno 
3  3 @[@] pqr !stu 
4  4 vwx @@@ yz 

J'ai essayé avec

> gsub('@.+[a-z] ', '!', df$text) 
[1] "abc !ghi" "[email protected] mno"  "[email protected]"  "vwx @@@ yz" 

Mais le résultat n'est pas le résultat souhaité. Toute aide est très appréciée.

Merci.

Répondre

3

Que diriez-vous

gsub("(^|)@(\\w)", "\\1!\\2", df$text) 
# [1] "abc !def ghi" "!jkl @ mno" "@[@] pqr !stu" "vwx @@@ yz" 

Cela correspond à un symbole @ au début d'une chaîne, ou après un espace. Ensuite, nous capturons le caractère de mot après le symbole @, et remplaçons @ par !.

courtoisie Explication des regex101.com:

  • (^|) est le 1er groupe Capturing; ^ affirme la position au début de la chaîne; | indique "ou"; espace vide correspond au caractère de l'espace littéralement
  • @ correspond au caractère @ littéralement (sensible à la casse)
  • (\\w) est le 2ème Capturing groupe, il désigne un caractère de mot

La chaîne de remplacement \\1!\\2 remplace le match d'expression régulière avec le premier groupe de capture (\\1), suivi de !, suivi par le second groupe de capture (\\2).

+0

Salut Rich Scriven, merci beaucoup pour la solution et une explication très détaillée de la logique qui la sous-tend. Cela fonctionne parfaitement. Passez une bonne journée. – user3550647

3

Vous pouvez utiliser un positif préanalyse (?=...)

gsub("@(?=[A-Za-z])", "!", df$text, perl = TRUE) 
[1] "abc !def ghi" "!jkl @ mno" "@[@] pqr !stu" "vwx @@@ yz" 

A partir des "expressions régulières utilisées dans R" page de documentation:

modèles (? = ...) et (?!. ..) sont des assertions positive et négative de largeur nulle: elles correspondent si une tentative de correspondance ... de la position actuelle réussit (ou non), mais n'utilise aucun caractère dans la chaîne en cours de traitement.

+0

Salut Sraffa, merci beaucoup pour votre réponse et l'explication. Votre solution fonctionne parfaitement. Bonne journée. – user3550647