从数据文件中删除非ASCII字符


74

我有一堆csv文件正在读入R中,并且包含在.rdata格式的package / data文件夹中 。不幸的是,数据中的非ASCII字符未能通过检查。该tools软件包具有两个功能来检查非ASCII字符(showNonASCIIshowNonASCIIfile),但我似乎找不到一个要删除/清理的字符。

在探索其他UNIX工具之前,最好在R中完成所有这些工作,以便我可以维护从原始数据到最终产品的完整工作流程。是否有任何现有的软件包/功能可以帮助我摆脱非ASCII字符?


尝试使用正则表达式,例如函数gsub。检查?regexp
aatrujillob 2012年

您知道read.csv()需要一个encoding参数,因此至少可以在R中处理这些参数?非ASCII字符会失败什么特定的检查?是在R(如果在此发布)还是在外部?
smci

Answers:


81

要简单地删除非ASCII字符,可以使用基数R的iconv()settings sub = ""。这样的事情应该起作用:

x <- c("Ekstr\xf8m", "J\xf6reskog", "bi\xdfchen Z\xfcrcher") # e.g. from ?iconv
Encoding(x) <- "latin1"  # (just to make sure)
x
# [1] "Ekstrøm"         "Jöreskog"        "bißchen Zürcher"

iconv(x, "latin1", "ASCII", sub="")
# [1] "Ekstrm"        "Jreskog"       "bichen Zrcher"

查找非ASCII字符,或查找文件中是否有字符,可以采用以下思路:

## Do *any* lines contain non-ASCII characters? 
any(grepl("I_WAS_NOT_ASCII", iconv(x, "latin1", "ASCII", sub="I_WAS_NOT_ASCII")))
[1] TRUE

## Find which lines (e.g. read in by readLines()) contain non-ASCII characters
grep("I_WAS_NOT_ASCII", iconv(x, "latin1", "ASCII", sub="I_WAS_NOT_ASCII"))
[1] 1 2 3

81

如今,一种更好的方法是使用stringi包,该包提供了用于通用unicode转换的功能。这使您可以尽可能保留原始文本:

x <- c("Ekstr\u00f8m", "J\u00f6reskog", "bi\u00dfchen Z\u00fcrcher")
x
#> [1] "Ekstrøm"         "Jöreskog"        "bißchen Zürcher"

stringi::stri_trans_general(x, "latin-ascii")
#> [1] "Ekstrom"          "Joreskog"         "bisschen Zurcher"

1
任何想法我如何使它与stringi一起工作-iconv("Klinik. der Univ. zu K_ln (AA\u0090R)","latin1","ASCII",sub="") => [1] "Klinik. der Univ. zu K_ln (AAR)"但是stringi::stri_trans_general("Klinik. der Univ. zu K_ln (AA\u0090R)", "latin-ascii") => [1] "Klinik. der Univ. zu K_ln (AA\u0090R)"
xbsd

stringi::stri_trans_general(x, "latin-ascii")删除文本中的某些非ASCII字符,但不删除其他字符。tools::showNonASCII显示不删除的字符有:零宽度空格,商标符号,欧元符号,狭窄的不间断空格。这是否意味着"latin-ascii"我的字符串的转换标识符错误?有没有一种直接的方法来找出正确的变换标识符?谢谢
乔什

2

要删除非ASCII字符的所有词语(从@Hadley借款代码),你可以使用包xfunfilterdplyr

x <- c("Ekstr\u00f8m", "J\u00f6reskog", "bi\u00dfchen Z\u00fcrcher", "alex")
x

x %>% 
  tibble(name = .) %>%
  filter(xfun::is_ascii(name)== T)
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.