2013-03-06 10 views
58

naturalmente potrei sostituire specifici argomenti come questo:sostituire più lettere con gli accenti con gsub

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

ma sicuramente c'è un modo più semplice per fare tutto questo in linea di onle, giusto? Non trovo l'aiuto di gsub per essere molto completo su questo.

+0

Se si desidera sostituire modelli diversi con la stessa cosa, dovrebbe essere possibile con 'lapply', ma come si desidera sostituire diversi modelli con stringhe diverse, penso che sarà necessario specificare in un modo o nell'altro. .. – juba

+2

Potresti essere in grado di usare 'chartr' per fare ciò. – Andrie

+30

La funzione 'gsubfn' nel pacchetto' gsubfn' è una generalizzazione di 'gsub' che può farlo in una chiamata:' gsubfn (".", Lista ("á" = "a", "é" = "e "," ó "=" o "), c (" á "," é "," ó "))' –

risposta

72

utilizzare la funzione di traduzione dei caratteri

chartr("áéó", "aeo", mydata) 
+2

+1 per indicare 'chartr()', che è esattamente la risposta alla domanda originale. –

+2

(+1) non l'aveva usato prima. molto bella! – Arun

+0

Questo è bello per i personaggi ... Ma funziona anche con caratteri speciali ad es. underscore, punti, ecc ... Non è nella domanda, sarebbe comunque interessante sapere qualcosa anche per questo caso ... – Joschi

29

Una domanda interessante! Credo che l'opzione più semplice è quella di ideare una funzione speciale, qualcosa di simile a un gsub "multi"():

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 
} 

che mi dà:

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

Non così elegante, ma funziona e fa quello che vuoi

7

Un altro mgsub implementazione utilizzando 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) 
} 
20

Forse questo può essere utile:

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

Sulla versione più recente di R che sto usando la chiamata 'iconv ('áéóÁÉÓçã', a =" ASCII // TRANSLIT ")' restituisce '" 'a'e'o'A'E'Oc ~ a " '. Il comportamento è cambiato nelle versioni R o ha a che fare con la mia codifica predefinita? – Aaron

+0

@'Aaron: non so se è un problema di codifica. Ho provato qui in R 3.3.1 e ho funzionato come previsto. – Rcoster

6

Un problema con alcune delle implementazioni di cui sopra (ad esempio, di Theodore Lytras) è che se i modelli sono più personaggi, possono entrare in conflitto nel caso in cui uno schema sia una sottostringa di un altro. Un modo per risolverlo è creare una copia dell'oggetto ed eseguire la sostituzione del modello in quella copia. Questo è implementato nel mio pacchetto bayesbio, disponibile su 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) 
} 

Qui è un banco di prova:

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

    res = mgsub(c("0", "1", "2"), c("10", "11", "12"), asdf) 
7

È possibile utilizzare stringi pacchetto per sostituire questi caratteri.

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

[1] "a" "e" "o" 
3

Questo è molto simile a @kith, ma in forma di funzione, e con i casi più comuni diacritcs:

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


removeDiscritics("test áéíóú") 

"test AEIOU"

1

È possibile utilizzare la funzione match. Qui match(x, y) restituisce l'indice di dove corrisponde l'elemento di x. Quindi è possibile utilizzare gli indici restituiti per suddividere un altro vettore (ad esempio z) che contiene le sostituzioni per i valori di x, opportunamente abbinati a . Nel tuo caso:

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

desired[match(mydata, mydata)] 

In un esempio più semplice, prendere in considerazione la situazione di seguito, in cui stavo cercando di sostituire a per 'alpha', 'b' per 'beta' e così via.

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

correlati alla risposta di Justin:

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

E si può sbarazzarsi dei nomi con names(*) <- NULL se si desidera.

Problemi correlati