2012-03-09 2 views
23

Я пытаюсь использовать пакет tm в R для выполнения некоторого текстового анализа. Я связал следующее:R tm package invalid input in 'utf8towcs'

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/"{}" \; 

как указано здесь Batch convert latin-1 files to utf-8 using iconv

Но я все еще получаю та же ошибка.

Буду признателен за любую помощь.

ответ

2

Это общая проблема с tm пакета (1, 2, 3).

Один не- R способ исправить это, чтобы использовать текстовый редактор, чтобы найти и заменить все орнаментальные символы (то есть. Те, с диакритическими знаками) в тексте перед загрузкой в ​​R (или использовать gsub в R). Например, вы искали и заменили все экземпляры O-umlaut в Öl-Teppich. Others имели успех с этим (я тоже), но если у вас есть тысячи отдельных текстовых файлов, очевидно, это не хорошо.

Для 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's 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 

Но это кажется немного счастливой случайности. Там должен быть более прямой способ. Сообщите нам, что сработает для вас!

+1

Спасибо за ваш ответ Бен! По какой-то причине эта же строка кода, которая не срабатывала для меня, работает сейчас. Я не знаю, было ли это еще одно счастливое совпадение :) Я ничего не изменил, просто запустите его, и на этот раз он работает без каких-либо икота. – maiaini

+0

Рад слышать, что вы получили его! – Ben

1

Если все в порядке игнорировать недопустимые входы, вы можете использовать обработку ошибок 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/

19

Это от тм FAQ:

он заменит неконвертируемых байты в yourCorpus со строками с указанием их шестнадцатеричные коды ,

Надеюсь, это поможет, для меня это так.

tm_map(yourCorpus, function(x) iconv(enc2utf8(x), sub = "byte")) 

http://tm.r-forge.r-project.org/faq.html

1

Используйте следующие шаги:

# 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) 
8

Я просто прервала эту проблему. Случайно вы используете машину с 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 на макинтоше и отлично работает без необходимости перекомпиляции.

1

Официальный FAQ, кажется, не работает в моей ситуации:

tm_map(yourCorpus, function(x) iconv(x, to='UTF-8-MAC', sub='byte')) 

Наконец я сделал это, используя для & кодирования функции:

for (i in 1:length(dataSet)) 
{ 
    Encoding(corpus[[i]])="UTF-8" 
} 
corpus <- tm_map(dataSet, tolower) 
4

Я бежал это на Mac и мое разочарование, я должен был определить грязную запись (поскольку это были твиты), чтобы решить. Так как в следующий раз, нет никакой гарантии записи такой же, я использовал следующую функцию

tm_map(yourCorpus, function(x) iconv(x, to='UTF-8-MAC', sub='byte')) 

, как было предложено выше.

Он работал как шарм

39

Ни один из вышеперечисленных ответов не работал для меня. Единственный способ обойти эту проблему - удалить все неграфические символы (http://stat.ethz.ch/R-manual/R-patched/library/base/html/regex.html).

Код этой простой

usableText=str_replace_all(tweets$text,"[^[:graph:]]", " ") 
+1

Это должно быть отмечено как решение. Он работает, и он популярен в течение многих лет, но OP не придерживался, чтобы отметить его как правильное. –

0

решение Чад не работает для меня. У меня было это встроенное в функцию, и она давала ошибку около iconv, которая нуждалась в векторе в качестве входа. Итак, я решил сделать преобразование, прежде чем создавать корпус.

myCleanedText <- sapply(myText, function(x) iconv(enc2utf8(x), sub = "byte")) 
9

Я думаю, что это ясно теперь, что проблема из-за смайликов, что ToLower не в состоянии понять

#to remove emojis 
dataSet <- iconv(dataSet, 'UTF-8', 'ASCII') 
2

Бывшие предложения не работает для меня.Я исследовал больше и нашел тот, который работал в следующем 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))