当我在R中导入Stata数据集(使用foreign包)时,导入有时包含无效的UTF-8字符。这本身就已经够令人不愉快的了,但是当我试图将对象转换为JSON(使用rjson包)时,它会破坏所有内容。如何识别字符串中的无效UTF-8字符并在此之后删除它们?
foreign
rjson
vc9ivgsu1#
另一个使用iconv和it参数sub的解决方案:字符串。如果不是NA(这里我将其设置为''),则用于替换输入中的任何不可转换字节。
iconv
sub
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
laawzig22#
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单词,您可以稍微修改上面的内容,并执行以下操作:
xfun
read_utf8
xfun:::invalid_utf8()
which(!is.na(x) & is.na(iconv(x, "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
nbewdwxp3#
另一种方法是在整个数据集上使用dspur删除坏字符:
library(dplyr) MyDate %>% mutate_at(vars(MyTextVar1, MyTextVar2), function(x){gsub('[^ -~]', '', x)})
其中MyData和MyTextVar是要删除坏苹果的数据集和文本变量。这可能不如改变编码那么健壮,但通常只是删除它们就可以了。
MyData
MyTextVar
jucafojl4#
您可以尝试使用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。由于我们无法访问您的数据,因此很难知道哪一个更合适。
latin1
4条答案
按热度按时间vc9ivgsu1#
另一个使用
iconv
和it参数sub
的解决方案:字符串。如果不是NA(这里我将其设置为''),则用于替换输入中的任何不可转换字节。这里请注意,如果我们选择正确的编码:
laawzig22#
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单词,您可以稍微修改上面的内容,并执行以下操作:
nbewdwxp3#
另一种方法是在整个数据集上使用dspur删除坏字符:
其中
MyData
和MyTextVar
是要删除坏苹果的数据集和文本变量。这可能不如改变编码那么健壮,但通常只是删除它们就可以了。jucafojl4#
您可以尝试使用
iconv
将它们转换为UTF-8字符串,而不是删除它们。您可以在您的情况下用更合适的编码替换
latin1
。由于我们无法访问您的数据,因此很难知道哪一个更合适。