web-dev-qa-db-fra.com

Remplacer plusieurs lettres par des accents par gsub

bien sûr, je pourrais remplacer des arguments spécifiques comme celui-ci:

    mydata=c("á","é","ó")
    mydata=gsub("á","a",mydata)
    mydata=gsub("é","e",mydata)
    mydata=gsub("ó","o",mydata)
    mydata

mais il y a sûrement un moyen plus facile de faire tout cela en ligne, non? Je ne trouve pas l'aide gsub très complète à ce sujet. 

62
Joschi

Utiliser la fonction de traduction de caractères

chartr("áéó", "aeo", mydata)
77
kith

Une question intéressante! Je pense que l'option la plus simple est de concevoir une fonction spéciale, quelque chose comme un "multi" gsub ()

mgsub <- function(pattern, replacement, x, ...) {
  if (length(pattern)!=length(replacement)) {
    stop("pattern and replacement do not have the same length.")
  }
  result <- x
  for (i in 1:length(pattern)) {
    result <- gsub(pattern[i], replacement[i], result, ...)
  }
  result
}

Ce qui me donne:

> mydata <- c("á","é","ó")
> mgsub(c("á","é","ó"), c("a","e","o"), mydata)
[1] "a" "e" "o"
31
Theodore Lytras

Peut-être que cela peut être utile: 

iconv('áéóÁÉÓçã', to="ASCII//TRANSLIT")
[1] "aeoAEOca"
23
Rcoster

Vous pouvez utiliser le package stringi pour remplacer ces caractères.

> stri_trans_general(c("á","é","ó"), "latin-ascii")

[1] "a" "e" "o"
8
Maciej

Une autre implémentation mgsub utilisant Reduce

mystring = 'This is good'
myrepl = list(c('o', 'a'), c('i', 'n'))

mgsub2 <- function(myrepl, mystring){
  gsub2 <- function(l, x){
   do.call('gsub', list(x = x, pattern = l[1], replacement = l[2]))
  }
  Reduce(gsub2, myrepl, init = mystring, right = T) 
}
7
Ramnath

Ceci est très similaire à @kith, mais sous forme de fonction et avec les cas les plus courants de diacritcs:

removeDiscritics <- function(string) {
  chartr(
     "ŠŽšžŸÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðñòóôõöùúûüýÿ"
    ,"SZszYAAAAAACEEEEIIIIDNOOOOOUUUUYaaaaaaceeeeiiiidnooooouuuuyy"
    , string
  )
}


removeDiscritics("test áéíóú")

"test aeiou"

6
Murta

Certaines des implémentations ci-dessus (par exemple celles de Theodore Lytras) posent un problème: si les motifs sont composés de plusieurs caractères, ils peuvent entrer en conflit dans le cas où un motif est une sous-chaîne d'un autre. Un moyen de résoudre ce problème consiste à créer une copie de l'objet et à effectuer le remplacement du modèle dans cette copie. Ceci est implémenté dans mon paquet bayesbio, disponible sur CRAN. 

mgsub <- function(pattern, replacement, x, ...) {
  n = length(pattern)
  if (n != length(replacement)) {
    stop("pattern and replacement do not have the same length.")
  }
  result = x
  for (i in 1:n) {
    result[grep(pattern[i], x, ...)] = replacement[i]
  }
  return(result)
}

Voici un cas de test: 

  asdf = c(4, 0, 1, 1, 3, 0, 2, 0, 1, 1)

  res = mgsub(c("0", "1", "2"), c("10", "11", "12"), asdf)
6
Andy McKenzie

Pas si élégant, mais ça marche et fait ce que tu veux

> diag(sapply(1:length(mydata), function(i, x, y) {
+   gsub(x[i],y[i], x=x)
+ }, x=mydata, y=c('a', 'b', 'c')))
[1] "a" "b" "c"
3
Jilber Urbina

Vous pouvez utiliser la fonction match. Ici match(x, y) renvoie l'index de y où l'élément de x correspond. Ensuite, vous pouvez utiliser les index renvoyés pour sous-définir un autre vecteur (par exemple, z) contenant les remplacements pour les valeurs de x, correctement associées à y. Dans ton cas:

mydata <- c("á","é","ó")
desired <- c('a', 'e', 'o')

desired[match(mydata, mydata)]

Dans un exemple plus simple, considérons la situation ci-dessous, où j’essayais de substituer a à 'alpha', 'b' à 'beta' et ainsi de suite.

x <- c('a', 'a', 'b', 'c', 'b', 'c', 'e', 'e', 'd')

y <- c('a', 'b', 'c', 'd', 'e')
z <- c('alpha', 'beta', 'gamma', 'delta', 'epsilon')

z[match(x, y)]
1
justin1.618

Relatif à la réponse de Justin:

> m <- c("á"="a", "é"="e", "ó"="o")
> m[mydata]
  á   é   ó 
"a" "e" "o" 

Et vous pouvez vous débarrasser des noms avec names(*) <- NULL si vous le souhaitez.

1
Dthal