R tm заблокировать недопустимый ввод в 'utf8towcs'
Я пытаюсь использовать пакет tm в R для выполнения некоторого текстового анализа. Я связал следующее:
require(tm)
dataSet <- Corpus(DirSource('tmp/'))
dataSet <- tm_map(dataSet, tolower)
Error in FUN(X[[6L]], ...) : invalid input 'RT @noXforU Erneut riesiger (Alt-)�lteppich im Golf von Mexiko (#pics vom Freitag) http://bit.ly/bw1hvU http://bit.ly/9R7JCf #oilspill #bp' in 'utf8towcs'
Проблема в том, что некоторые символы недопустимы. Я хотел бы исключить недопустимые символы из анализа либо изнутри R, либо перед импортом файлов для обработки.
Я попытался использовать iconv для преобразования всех файлов в utf-8 и исключить все, что не может быть преобразовано в следующее:
find . -type f -exec iconv -t utf-8 "{}" -c -o tmpConverted/"{}" \;
как указано здесь Пакетное преобразование файлов latin-1 в utf-8 с помощью iconv
Но я все равно получаю ту же ошибку.
Буду признателен за любую помощь.
Ответы
Ответ 1
Ни один из вышеперечисленных ответов не работал у меня. Единственный способ обойти эту проблему - удалить все неграфические символы (http://stat.ethz.ch/R-manual/R-patched/library/base/html/regex.html).
Код - это простой
usableText=str_replace_all(tweets$text,"[^[:graph:]]", " ")
Ответ 2
Это из tm faq:
он заменит неконвертируемые байты в yourCorpus на строки показывая свои шестнадцатеричные коды.
Надеюсь, это поможет, для меня это так.
tm_map(yourCorpus, function(x) iconv(enc2utf8(x), sub = "byte"))
http://tm.r-forge.r-project.org/faq.html
Ответ 3
Я только что столкнулся с этой проблемой. Случайно вы используете машину с OSX? Я и, кажется, проследил эту проблему до определения набора символов, которое R скомпилировано в этой операционной системе (см. https://stat.ethz.ch/pipermail/r-sig-mac/2012-July/009374.html)
Что я видел, так это то, что с помощью решения из FAQ
tm_map(yourCorpus, function(x) iconv(enc2utf8(x), sub = "byte"))
дал мне это предупреждение:
Warning message:
it is not known that wchar_t is Unicode on this platform
Это я проследил до функции enc2utf8
. Плохая новость заключается в том, что это проблема с моей базовой ОС, а не с R.
Итак, вот что я сделал в качестве работы:
tm_map(yourCorpus, function(x) iconv(x, to='UTF-8-MAC', sub='byte'))
Это заставляет iconv использовать кодировку utf8 на macintosh и отлично работает без необходимости перекомпилировать.
Ответ 4
Я думаю, что теперь ясно, что проблема заключается в том, что emojis, что tolower не способен понять
#to remove emojis
dataSet <- iconv(dataSet, 'UTF-8', 'ASCII')
Ответ 5
Я выполнял это на Mac и, к моему разочарованию, мне пришлось идентифицировать грязную запись (поскольку это были твиты) для решения. Поскольку в следующий раз нет гарантии того, что запись будет одинаковой, я использовал следующую функцию
tm_map(yourCorpus, function(x) iconv(x, to='UTF-8-MAC', sub='byte'))
как было предложено выше.
Он работал как шарм
Ответ 6
Это обычная проблема с пакетом tm
(1, 2, 3).
Один из способов не исправить это - использовать текстовый редактор для поиска и замены всех модных символов (т.е. с диакритикой) в тексте перед загрузкой в R
(или использовать gsub
в R
). Например, вы искали и заменили все экземпляры O-umlaut в Öl-Teppich. Другие имели успех с этим (у меня тоже), но если у вас есть тысячи отдельных текстовых файлов, очевидно, это не хорошо.
Для решения R
я обнаружил, что использование VectorSource
вместо DirSource
, похоже, решает проблему:
# I put your example text in a file and tested it with both ANSI and
# UTF-8 encodings, both enabled me to reproduce your problem
#
tmp <- Corpus(DirSource('C:\\...\\tmp/'))
tmp <- tm_map(dataSet, tolower)
Error in FUN(X[[1L]], ...) :
invalid input 'RT @noXforU Erneut riesiger (Alt-)Öl–teppich im Golf von Mexiko (#pics vom Freitag) http://bit.ly/bw1hvU http://bit.ly/9R7JCf #oilspill #bp' in 'utf8towcs'
# quite similar error to what you got, both from ANSI and UTF-8 encodings
#
# Now try VectorSource instead of DirSource
tmp <- readLines('C:\\...\\tmp.txt')
tmp
[1] "RT @noXforU Erneut riesiger (Alt-)Öl–teppich im Golf von Mexiko (#pics vom Freitag) http://bit.ly/bw1hvU http://bit.ly/9R7JCf #oilspill #bp"
# looks ok so far
tmp <- Corpus(VectorSource(tmp))
tmp <- tm_map(tmp, tolower)
tmp[[1]]
rt @noxforu erneut riesiger (alt-)öl–teppich im golf von mexiko (#pics vom freitag) http://bit.ly/bw1hvu http://bit.ly/9r7jcf #oilspill #bp
# seems like it worked just fine. It worked for best for ANSI encoding.
# There was no error with UTF-8 encoding, but the Ö was returned
# as ã– which is not good
Но это похоже на случайное совпадение. Там должен быть более прямой способ. Сообщите нам, что сработает для вас!
Ответ 7
Первые предложения не помогли мне. Я исследовал больше и нашел тот, который работал в следующем https://eight2late.wordpress.com/2015/05/27/a-gentle-introduction-to-text-mining-using-r/
#Create the toSpace content transformer
toSpace <- content_transformer(function(x, pattern) {return (gsub(pattern," ",
x))})
# Apply it for substituting the regular expression given in one of the former answers by " "
your_corpus<- tm_map(your_corpus,toSpace,"[^[:graph:]]")
# the tolower transformation worked!
your_corpus <- tm_map(your_corpus, content_transformer(tolower))
Ответ 8
Если правильно игнорировать недопустимые входы, вы можете использовать обработку ошибок R. например:
dataSet <- Corpus(DirSource('tmp/'))
dataSet <- tm_map(dataSet, function(data) {
#ERROR HANDLING
possibleError <- tryCatch(
tolower(data),
error=function(e) e
)
# if(!inherits(possibleError, "error")){
# REAL WORK. Could do more work on your data here,
# because you know the input is valid.
# useful(data); fun(data); good(data);
# }
})
Здесь есть еще один пример: http://gastonsanchez.wordpress.com/2012/05/29/catching-errors-when-using-tolower/
Ответ 9
Используйте следующие шаги:
# First you change your document in .txt format with encoding UFT-8
library(tm)
# Set Your directoryExample ("F:/tmp").
dataSet <- Corpus(DirSource ("/tmp"), readerControl=list(language="english)) # "/tmp" is your directory. You can use any language in place of English whichever allowed by R.
dataSet <- tm_map(dataSet, tolower)
Inspect(dataSet)
Ответ 10
Официальный FAQ, похоже, не работает в моей ситуации:
tm_map(yourCorpus, function(x) iconv(x, to='UTF-8-MAC', sub='byte'))
Наконец, я сделал это с помощью функции for и Encoding:
for (i in 1:length(dataSet))
{
Encoding(corpus[[i]])="UTF-8"
}
corpus <- tm_map(dataSet, tolower)
Ответ 11
Решение Чада не работало для меня. У меня было это встроенное в функцию, и она давала ошибку о iconv
, которая нужна для ввода вектора. Итак, я решил сделать преобразование, прежде чем создавать корпус.
myCleanedText <- sapply(myText, function(x) iconv(enc2utf8(x), sub = "byte"))
Ответ 12
Я смог исправить это, преобразовывая данные обратно в текстовый формат, используя эту строку кода
corpus <- tm_map(corpus, PlainTextDocument)
благодаря пользователю https://stackoverflow.com/users/4386239/paul-gowder
для его ответа здесь
fooobar.com/questions/202511/...
Ответ 13
Я часто сталкивался с этой проблемой, и этот пост всегда был первым. Раньше я использовал верхнее решение, но он может вычеркивать символы и заменять их мусором (например, преобразование it’s
в it’s
).
Я обнаружил, что на самом деле есть гораздо лучшее решение! Если вы установите пакет stringi
, вы можете заменить tolower()
на stri_trans_tolower()
, а затем все должно работать нормально.