R tm包中的无效输入< utf8towcs'

时间:2012-03-09 16:10:20

标签: r utf-8 iconv text-mining

我正在尝试使用R中的tm包来执行一些文本分析。我绑了以下内容:

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

所指出的那样

但我仍然得到同样的错误。

我很感激任何帮助。

13 个答案:

答案 0 :(得分:54)

上述答案都不适合我。解决此问题的唯一方法是删除所有非图形字符(http://stat.ethz.ch/R-manual/R-patched/library/base/html/regex.html)。

代码就是这么简单

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

答案 1 :(得分:24)

这是来自tm faq:

  

它将用字符串替换yourCorpus中的不可转换字节   显示他们的十六进制代码。

我希望这对我有帮助。

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

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

答案 2 :(得分:13)

我认为现在很清楚,问题是由于表现力不能理解的表情符号

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

答案 3 :(得分:10)

我刚刚遇到这个问题。您是否正在使用运行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在macintosh上使用utf8编码,并且无需重新编译即可正常工作。

答案 4 :(得分:4)

我一直在Mac上运行这个并且令我沮丧,我必须确定要解决的犯规记录(因为这些是推文)。由于下次没有保证记录相同,我使用了以下功能

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

如上所述。

它像魅力一样

答案 5 :(得分:2)

这是tm包(123)的常见问题。

修复它的一种非R方法是在将文本加载到R之前使用文本编辑器查找并替换文本中所有花哨的字符(即带有变音符号的字符)(或在gsub中使用R。例如,您将搜索并替换Öl-Teppich中O-umlaut的所有实例。 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

但这似乎是一个幸运的巧合。必须有一个更直接的方式。请告诉我们什么对您有用!

答案 6 :(得分: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))

答案 7 :(得分:1)

如果忽略无效输入,可以使用R的错误处理。 e.g:

  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/

答案 8 :(得分: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)

答案 9 :(得分:1)

官方常见问题解答似乎无法解决我的问题:

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

最后我使用for&amp; amp;编码功能:

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

答案 10 :(得分:1)

我经常遇到这个问题,这个Stack Overflow帖子总是首先出现的。我之前使用过顶级解决方案,但它可以删除字符并将其替换为垃圾(例如将it’s转换为it’s)。

我发现实际上有更好的解决方案!如果您安装stringi软件包,则可以将tolower()替换为stri_trans_tolower(),然后一切正常。

答案 11 :(得分:0)

我能够通过使用这行代码将数据转换回纯文本格式来修复它

corpus <- tm_map(corpus, PlainTextDocument)

感谢用户https://stackoverflow.com/users/4386239/paul-gowder

他在这里的回应

https://stackoverflow.com/a/29529990/815677

答案 12 :(得分:0)

我在Mac中遇到了同样的问题,可通过以下解决方案解决。

raw_data <- read.csv(file.choose(), stringsAsFactors = F,  encoding="UTF-8")

raw_data$textCol<- iconv(raw_data$textCol, "ASCII", "UTF-8", sub="byte")

data_corpus <- VCorpus(VectorSource(raw_data$textCol))

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

corpus_clean <- tm_map(data_corpus, content_transformer(tolower))