【问题标题】:How to identify/delete non-UTF-8 characters in R如何识别/删除 R 中的非 UTF-8 字符
【发布时间】:2013-06-21 21:26:12
【问题描述】:

当我在 R(使用 foreign 包)中导入 Stata 数据集时,导入有时会包含无效的字符 UTF-8。这本身就很令人不快,但是当我尝试将对象转换为JSON(使用rjson 包)时,它会破坏一切。

如何识别字符串中的无效-UTF-8-字符并在此之后删除它们?

【问题讨论】:

    标签: r utf-8 stata


    【解决方案1】:

    您可以尝试使用 iconv 将它们转换为 UTF-8 字符串,而不是删除它们。

    require(foreign)
    dat <- read.dta("data.dta")
    
    for (j in seq_len(ncol(dat))) {
       if (class(dat[, j]) == "factor")
           levels(dat[, j]) <- iconv(levels(dat[, j]), from = "latin1", to = "UTF-8")
    }
    

    您可以用更适合您的情况的编码替换 latin1。 由于我们无法访问您的数据,因此很难知道哪个更合适。

    【讨论】:

      【解决方案2】:

      使用iconv 和它的参数sub 的另一种解决方案:字符串。如果不是 NA(这里我设置为 ''),它用于替换输入中任何不可转换的字节。

      x <- "fa\xE7ile"
      Encoding(x) <- "UTF-8"
      iconv(x, "UTF-8", "UTF-8",sub='') ## replace any non UTF-8 by ''
      "faile"
      

      这里注意,如果我们选择正确的编码:

      x <- "fa\xE7ile"
      Encoding(x) <- "latin1"
      xx <- iconv(x, "latin1", "UTF-8",sub='')
      facile
      

      【讨论】:

        【解决方案3】:

        在整个数据集上使用 dplyr 删除坏字符的另一种方法:

        library(dplyr)
        
        MyDate %>%
            mutate_at(vars(MyTextVar1, MyTextVar2), function(x){gsub('[^ -~]', '', x)})
        

        其中MyDataMyTextVar 是要从中删除坏苹果的数据集和文本变量。这可能不如更改编码那么健壮,但通常只需删除它们就可以了。

        【讨论】:

        • 基于 Tyler 的回答,您还可以考虑以所有字符列为目标的 MyDate %&gt;% mutate_if(is.character, ~gsub('[^ -~]', '', .)) 或以所有列为目标的 MyData %&gt;% mutate_all(~gsub('[^ -~]', '', .))
        • 这会删除比需要更多的字符。问题要求非 UTF8,而不是非 ASCII。
        【解决方案4】:

        Yihui 的xfun 包有一个函数read_utf8,它试图读取一个文件并假设它被编码为UTF-8。如果文件包含非 UTF-8 行,则会触发警告,让您知道哪些行包含非 UTF-8 字符。在后台,它使用了一个非导出函数xfun:::invalid_utf8(),它就是以下内容:which(!is.na(x) &amp; is.na(iconv(x, "UTF-8", "UTF-8")))

        要在字符串中检测特定的非 UTF-8 单词,您可以稍微修改上面的内容并执行以下操作:

        invalid_utf8_ <- function(x){
        
          !is.na(x) & is.na(iconv(x, "UTF-8", "UTF-8"))
        
        }
        
        detect_invalid_utf8 <- function(string, seperator){
        
          stringSplit <- unlist(strsplit(string, seperator))
        
          invalidIndex <- unlist(lapply(stringSplit, invalid_utf8_))
        
          data.frame(
            word = stringSplit[invalidIndex],
            stringIndex = which(invalidIndex == TRUE)
          )
        
        }
        
        x <- "This is a string fa\xE7ile blah blah blah fa\xE7ade"
        
        detect_invalid_utf8(x, " ")
        
        #     word stringIndex
        # 1 façile    5
        # 2 façade    9
        

        【讨论】:

          猜你喜欢
          • 2011-04-04
          • 2018-01-23
          • 2020-06-01
          • 1970-01-01
          • 2011-12-04
          • 2018-01-05
          • 2012-11-10
          • 2010-09-27
          • 1970-01-01
          相关资源
          最近更新 更多