2012-03-09 6 views
23

Sto provando a utilizzare il pacchetto tm in R per eseguire alcune analisi del testo. Ho legato il seguente:R tm pacchetto input non valido 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' 

Il problema è che alcuni caratteri non sono validi. Vorrei escludere i caratteri non validi dall'analisi dall'interno di R o prima di importare i file per l'elaborazione.

Ho provato ad utilizzare iconv per convertire tutti i file in UTF-8 ed escludere tutto ciò che non può essere convertito in che modo seguente:

find . -type f -exec iconv -t utf-8 "{}" -c -o tmpConverted/"{}" \; 

come sottolineato qui Batch convert latin-1 files to utf-8 using iconv

Ma ho ancora ottenere lo stesso errore.

Apprezzerei qualsiasi aiuto.

risposta

2

Questo è un problema comune con il pacchetto tm (1, 2, 3).

Uno non R modo per risolvere il problema è quello di utilizzare un editor di testo per trovare e sostituire tutti i personaggi di fantasia (es. Quelli con segni diacritici) nel testo prima di caricarla nel R (o usare gsub in R). Ad esempio, dovresti cercare e sostituire tutte le occorrenze della O-umlaut in Öl-Teppich. Others hanno avuto successo con questo (anch'io ho), ma se hai migliaia di singoli file di testo ovviamente questo non va bene.

Per una soluzione R, ho trovato che l'uso VectorSource invece di DirSource sembra risolvere il problema:

# 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 

Ma questo sembra un po 'una fortunata coincidenza. Ci deve essere un modo più diretto a riguardo. Fateci sapere cosa funziona per voi!

+1

Grazie per la tua risposta Ben! Per qualche ragione, quella stessa riga di codice che non funziona per me funziona ora. Non so se questa è un'altra fortunata coincidenza :) Non ho cambiato nulla, solo rieseguo e questa volta funziona senza intoppi. – maiaini

+0

Felice di sentire che hai funzionato! – Ben

1

Se è giusto ignorare gli input non validi, è possibile utilizzare la gestione degli errori di R. es:

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); 
    # } 
    }) 

V'è un ulteriore esempio qui: http://gastonsanchez.wordpress.com/2012/05/29/catching-errors-when-using-tolower/

19

Questo è dal faq tm:

sostituirà byte non convertibili in yourCorpus con stringhe mostra i relativi codici esadecimali .

Spero che questo aiuti, per me lo fa.

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

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

1

utilizzare le seguenti operazioni:

# 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

ho appena conciliarsi con questo problema. Per caso stai usando una macchina con OSX?Io sono e sembra di aver tracciato il problema alla definizione del set di caratteri che R è compilato contro su questo sistema operativo (vedi https://stat.ethz.ch/pipermail/r-sig-mac/2012-July/009374.html)

quello che stavo vedendo è che utilizzando la soluzione dalla FAQ

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

mi stava dando questo avvertimento:

Warning message: 
it is not known that wchar_t is Unicode on this platform 

questo ho tracciato alla funzione enc2utf8. Cattiva notizia è che questo è un problema con il mio sistema operativo sottostante e non R.

Così qui è quello che ho fatto come un lavoro intorno:

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

Questo forze iconv di utilizzare la codifica utf8 sul Macintosh e funziona bene senza la necessità di ricompilare.

1

La FAQ ufficiale sembra essere non funziona nella mia situazione:

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

Infine ho fatto usando il per & codifica funzione:

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

Sono stato in esecuzione questo su Mac e per la mia frustrazione, ho dovuto identificare il fallo (come questi erano i tweet) da risolvere. Dal momento che la prossima volta, non v'è alcuna garanzia del record è lo stesso, ho usato la seguente funzione

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

come suggerito sopra.

ha funzionato come un fascino

39

Nessuna delle risposte di cui sopra ha funzionato per me. L'unico modo per ovviare a questo problema era quello di rimuovere tutti i caratteri non grafici (http://stat.ethz.ch/R-manual/R-patched/library/base/html/regex.html).

il codice è questo semplice

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

Questo dovrebbe essere contrassegnato come la soluzione. Funziona ed è stato popolare per anni, ma l'OP non si è limitato a contrassegnarlo come corretto. –

0

soluzione di Chad non funzionava per me. Ho inserito questo in una funzione e stava dando un errore su iconv che necessitava di un vettore come input. Così, ho deciso di fare la conversione prima di creare il corpus.

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

penso che sia ormai chiaro che il problema è a causa delle emoji che tolower non è in grado di capire

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

Gli ex proposte non ha funzionato per me.Ho studiato di più e ho trovato quello che ha funzionato nel seguente 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))