如何识别/删除R中的非UTF-8字符

问题描述 投票:0回答:4

当我在 R 中导入 Stata 数据集(使用

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

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

r utf-8 stata
4个回答
45
投票

使用

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

7
投票

Yihui 的

xfun
包有一个函数
read_utf8
,它尝试读取文件并假设它编码为 UTF-8。如果文件包含非 UTF-8 行,则会触发警告,让您知道哪些行包含非 UTF-8 字符。在底层,它使用一个非导出函数
xfun:::invalid_utf8()
,如下所示:
which(!is.na(x) & 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

4
投票

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

library(dplyr)

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

其中

MyData
MyTextVar
是要从中删除坏苹果的数据集和文本变量。这可能不如更改编码那么健壮,但通常删除它们就很好而且更容易。


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
替换为更适合您情况的编码。 由于我们无法访问您的数据,因此很难知道哪一个更合适。

© www.soinside.com 2019 - 2024. All rights reserved.