用gsub的重音替换多个字母


68

当然,我可以这样替换特定的参数:

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

但是肯定有一种更简单的方法可以在线完成所有操作,对吗?我发现gsub在这方面的帮助不是很全面。


如果您想用同一件事替换不同的模式,则应该可以用lapply,但是当您想用不同的字符串替换不同的模式时,我认为您仍然必须以一种或另一种方式指定这些模式...
juba

2
您也许可以使用chartr此功能。
Andrie

30
软件包中的gsubfn函数gsubfn是一个概括的函数gsub,可以一次调用完成该任务: gsubfn(".", list("á"="a", "é"="e", "ó"="o"), c("á","é","ó"))
G. Grothendieck 2013年

@ G.Grothendieck。太好了,并且适用于所有类型的字符。非常有价值的评论。谢谢!
2013年

1
对于寻求该问题更一般解决方案的人们,这里有一个更有用的答案:stackoverflow.com/a/7664655/1036500
2014年

Answers:


83

使用字符翻译功能

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

这对于角色来说很酷...但这也可以用于特殊字符,例如下划线,点等...这不在问题之列,对于这种情况了解一些信息还是很有趣的……
Joschi

@Joschi,您的问题没有谈论。我认为您必须逃脱它们,因为它们是特殊字符……
Arun

33

一个有趣的问题!我认为最简单的选择是设计一个特殊功能,例如“ 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
}

这给了我:

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

26

也许这可能是有用的:

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

在我使用的最新版本的R中,iconv('áéóÁÉÓçã', to="ASCII//TRANSLIT")返回"'a'e'o'A'E'Oc~a"。行为是否在R版本之间发生了变化,还是与我的默认编码有关?
亚伦

@Aaron:不知道是否是编码问题。我在R 3.3.1上尝试过,并按预期工作。
Rcoster '16

11

您可以使用stringi包来替换这些字符。

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

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

9

这与@kith非常相似,但采用函数形式,并且具有最常见的故障情况:

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


removeDiscritics("test áéíóú")

“测试aeiou”


简单而伟大
HAVB

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) 
}

7

上面的某些实现(例如Theodore 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)


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


0

在这种情况下,没有太多意义,但是如果它们只有两个,则还可以将它们与gsub结合使用:

mydata <- gsub("á","a", gsub("é","e",mydata))

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.