2013-03-06 2 views
58

, конечно, я мог бы заменить конкретные аргументы, как это:Заменить несколько букв с акцентами с GSUB

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

но наверняка есть более простой способ сделать это все в onle линии, не так ли? Я не нахожу помощь gsub, чтобы быть очень всеобъемлющей на этом.

+0

Если вы хотите заменить разные шаблоны одним и тем же, это должно быть возможно с помощью 'lapply', но поскольку вы хотите заменить разные шаблоны разными строками, я думаю, вам все равно придется указать их так или иначе. .. – juba

+2

Возможно, вы сможете использовать 'chartr' для этого. – Andrie

+30

Функция 'gsubfn' в пакете' gsubfn' является обобщением 'gsub', который может сделать это за один вызов:' gsubfn (".", List ("á" = "a", "é" = "e "," - "=" o "), c (" á "," é "," - "))' –

ответ

72

Используйте функцию перевода символов

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

+1 для указания 'chartr()', что является ответом на исходный вопрос. –

+2

(+1) раньше не использовал этот. очень хорошо! – Arun

+0

Это классно для персонажей ... Но это также работает со специальными символами, например. подчеркивания, точки и т. д. Это не входит в вопрос, все равно было бы интересно узнать что-то для этого случая ... – Joschi

29

Интересный вопрос! Я думаю, что самый простой вариант разработать специальную функцию, что-то вроде "мульти" 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 
} 

Который дает мне:

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

Не так изящно, но он работает и делает то, что вы хотите

> 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" 
7

Другой mgsub реализация с использованием 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

Может быть, это может быть полезно:

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

В самой последней версии R, что я использую вызов 'iconv ('áéóÁÉÓçã', to =" ASCII // TRANSLIT ")' возвращает '" 'a'e'o'A'E'Oc ~ a " '. Было ли поведение изменено в R-версиях, или это связано с моей кодировкой по умолчанию? – Aaron

+0

@Aaron: Не знаю, является ли проблема кодирования. Я пробовал здесь в R 3.3.1 и работал, как ожидалось. – Rcoster

6

Проблема с некоторыми из перечисленных выше реализаций (например, Теодор Lytras в) в том, что если шаблоны несколько символов, они могут конфликтовать в случае, если один шаблон является подстрокой другого. Способ решения этой проблемы - создать копию объекта и выполнить замену шаблона в этой копии. Это реализовано в моем пакете bayesbio, доступном на 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) 
} 

Вот тестовый пример:

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

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

Вы можете использовать stringi пакет, чтобы заменить эти символы.

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

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

Это очень похоже на @kith, но в виде функции, а также с наиболее распространенными случаями diacritcs:

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


removeDiscritics("test áéíóú") 

"тест AEIOU"

1

Вы можете использовать match функция. Здесь match(x, y) возвращает индекс y, где сопоставляется элемент x. Затем вы можете использовать возвращаемые индексы, чтобы подмножество другого вектора (например, z), который содержит замены для значений x, соответственно соответствующих y. В вашем случае:

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

desired[match(mydata, mydata)] 

В более простом примере, рассмотрим ситуацию ниже, где я пытался заменить a для 'alpha', 'b' для 'beta' и так далее.

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

, связанные с ответом Джастина:

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

И вы можете избавиться от имен с names(*) <- NULL, если вы хотите.

Смежные вопросы