有几种方法。其中两种已经根据stringi
或stringr
包进行了建议。
另一种解决方案使用gsubfn
包。
text <- "ae = ä und oe = ö, UE = Ü. I also want Ä to be AE and not Ae"
require(gsubfn)
gsubfn(".", list("ä"="ae", "ö"="oe", "ü"="ue", "Ä" = "AE", "Ö" = "OE", "Ü" = "UE"), text)
当然,我们也可以自己编写函数,因为你可能不想为了一个单一的函数加载一个包(我个人尽量避免这种情况)。
replace_umlauts <- function(x) {
umlauts <- "äöü"
UMLAUTS <- "ÄÖÜ"
x <- gsub(pattern = paste0("([", UMLAUTS, "])"), replacement = "\\1E", x)
x <- gsub(pattern = paste0("([", umlauts, "])"), replacement = "\\1e", x)
x <- chartr(old = paste0(UMLAUTS, umlauts), new = "AOUaou", x)
return(x)
}
replace_umlauts(text)
有趣的部分是基准测试。
require(microbenchmark)
require(stringi)
require(stringr)
require(gsubfn)
microbenchmark(
myown = replace_umlauts(text),
stringi = stringi::stri_replace_all_fixed(text, c("ä", "ö", "ü", "Ä", "Ö", "Ü"), c("ae", "oe", "ue", "AE", "OE", "UE"), vectorize_all = FALSE),
stringr = stringr::str_replace_all(text, c("ü" = "ue", "ä" = "ae", "ö" = "oe", "Ä" = "AE", "Ö" = "OE", "Ü" = "UE")),
gsubfn = gsubfn(".", list("ä"="ae", "ö"="oe", "ü"="ue", "Ä" = "AE", "Ö" = "OE", "Ü" = "UE"), text),
times = 500L
)
结果如下:
Unit: microseconds
expr min lq mean median uq max neval
myown 18.1 23.50 28.8510 30.45 32.6 63.3 500
stringi 10.5 14.10 17.3808 17.80 19.8 46.3 500
stringr 332.3 353.40 375.5458 371.85 387.5 586.1 500
gsubfn 996.5 1042.55 1104.7458 1057.45 1075.2 7547.5 500
最快的解决方案是stringi::stri_replace_all_fixed
。它比第二好的解决方案快近一倍,比stringr
快10倍。在速度方面唯一可以接受的替代方案是自制的replace_umlauts
函数。
stringr::str_replace_all('üïëäö', c('ü' = 'ue', 'ï' = 'ie', 'ë' = 'ee', 'ä' = 'ae','ö' = 'oe'))
(如果您喜欢,可以添加大写字母),则可以使用stringr::str_replace_all
一次性替换它们所有。不过,您可能需要深入了解 stringi;您可以使用stringi::stri_trans_general('üïëäö', 'latin-ascii')
删除重音符号,但它不会插入“e”字符。 - alistaire