web-dev-qa-db-fra.com

Remplacer plusieurs chaînes dans une instruction gsub () ou chartr () dans R?

J'ai une variable de chaîne contenant l'alphabet [a-z], l'espace [] et l'apostrophe ['], par exemple. x <- "a'b c" Je veux remplacer l'apostrophe ['] par un blanc [] et remplacer l'espace [] par un trait de soulignement [_].

x <- gsub("'", "", x)
x <- gsub(" ", "_", x)

Cela fonctionne absolument, mais quand j'ai beaucoup de condition, le code devient moche. Par conséquent, je veux utiliser chartr(), mais chartr() ne peut pas traiter les blancs, par exemple.

x <- chartr("' ", "_", x) 
#Error in chartr("' ", "_", "a'b c") : 'old' is longer than 'new'

Existe-t-il un moyen de résoudre ce problème? Merci!

13
Eric Chang

Vous pouvez utiliser gsubfn

library(gsubfn)
gsubfn(".", list("'" = "", " " = "_"), x)
# [1] "ab_c"

De même, nous pouvons également utiliser mgsub qui permet un remplacement multiple par plusieurs modèles pour rechercher

mgsub::mgsub(x, c("'", " "), c("", "_"))
#[1] "ab_c"
15
Ronak Shah

Je suis fan de la syntaxe fournie par les opérateurs %<>% Et %>% Du package magrittr.

library(magrittr)

x <- "a'b c"

x %<>%
  gsub("'", "", .) %>%
  gsub(" ", "_", .) 
x
##[1] "ab_c"

gusbfn est merveilleux, mais j'aime le chaînage %>% le permet.

19
Peter

J'opterais également pour une solution magrittr et/ou dplyr. Cependant, je préfère ne pas faire une nouvelle copie de l'objet, surtout s'il est dans une fonction et peut être retourné à moindre coût.

c'est à dire.

return(
  catInTheHat %>% gsub('Thing1', 'Thing2', .) %>% gsub('Red Fish', 'Blue 
    Fish', .)
)

...etc.

2
d8aninja
gsub("\\s", "", chartr("' ", " _", x)) # Use whitespace and then remove it
1
zhan2383

J'irais avec la fonction assez rapide stri_replace_all_fixed de la bibliothèque ( stringi ):

library(stringi)    
stri_replace_all_fixed("a'b c", pattern = c("'", " "), replacement = c("", "_"), vectorize_all = FALSE)

Voici un benchmark prenant en compte la plupart des autres soultions suggérées:

library(stringi)
library(microbenchmark)
library(gsubfn)
library(mgsub)
library(magrittr)
library(dplyr)

x_gsubfn <-
x_mgsub <-
x_nested_gsub <-
x_magrittr <-
x_stringi <- "a'b c"

microbenchmark("gsubfn" = { gsubfn(".", list("'" = "", " " = "_"), x_gsubfn) },
               "mgsub" = { mgsub::mgsub(x_mgsub, c("'", " "), c("", "_")) },
               "nested_gsub" = { gsub("Find", "Replace", gsub("Find","Replace", x_nested_gsub)) },
               "magrittr" = { x_magrittr %<>% gsub("'", "", .) %>% gsub(" ", "_", .) },
               "stringi" = { stri_replace_all_fixed(x_stringi, pattern = c("'", " "), replacement = c("", "_"), vectorize_all = FALSE) }
               )

Unit: microseconds
        expr     min       lq      mean   median       uq     max neval
      gsubfn 458.217 482.3130 519.12820 513.3215 538.0100 715.371   100
       mgsub 180.521 200.8650 221.20423 216.0730 231.6755 460.587   100
 nested_gsub  14.615  15.9980  17.92178  17.7760  18.7630  40.687   100
    magrittr 113.765 133.7125 148.48202 142.9950 153.0680 296.261   100
     stringi   3.950   7.7030   8.41780   8.2960   9.0860  26.071   100
1
ismirsehregal

Je pense que gsub imbriqué fera le travail.

gsub("Find","Replace",gsub("Find","Replace",X))
1
Atul