Как идентифицировать/удалить символы не UTF-8 в R
Когда я импортирую набор данных Stata в R (используя пакет foreign
), импорт иногда содержит недопустимые символы UTF-8
. Само по себе это достаточно неприятно, но все ломается, как только я пытаюсь преобразовать объект в JSON
(используя пакет rjson
).
Как я могу определить недействительный- UTF-8
-characters в строке и удалить их после этого?
Ответы
Ответ 1
Другое решение, использующее 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
Ответ 2
Вместо их удаления вы можете попытаться преобразовать их в строку UTF-8, используя iconv
.
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
на более подходящее приложение в вашем случае.
Поскольку у нас нет доступа к вашим данным, трудно понять, какой из них будет более подходящим.
Ответ 3
Другой подход для удаления плохих символов с использованием dplyr для всего набора данных:
library(dplyr)
MyDate %>%
mutate_at(vars(MyTextVar1, MyTextVar2), function(x){gsub('[^ -~]', '', x)})
Где MyData
и MyTextVar
- набор данных и текстовые переменные для удаления плохих парней. Это может быть менее надежно, чем изменение кодировки, но часто бывает проще и проще их просто удалить.
Ответ 4
Пакет 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