Windows上的R:字符编码地狱

use*_*636 23 csv encoding r utf-8 non-ascii-characters

我正在尝试将编码为OEM-866(西里尔语字符集)的CSV导入到Windows上的R中.我还有一份已经转换为UTF-8无副BOM的副本.一旦指定了编码,这两个文件都可以被我的系统上的所有其他应用程序读取.

此外,在Linux上,R可以使用指定的编码读取这些特定文件.我也可以在Windows上读取CSV如果我没有指定"fileEncoding"参数,但这会导致文本不可读.当我在Windows上指定文件编码时,对于OEM和Unicode文件,我总是会遇到以下错误:

原始OEM文件导入:

> oem.csv <- read.table("~/csv1.csv", sep=";", dec=",", quote="",fileEncoding="cp866")   #result:  failure to import all rows
Warning messages:
1: In scan(file, what, nmax, sep, dec, quote, skip, nlines, na.strings,  :
  invalid input found on input connection '~/Revolution/RProject1/csv1.csv'
2: In scan(file, what, nmax, sep, dec, quote, skip, nlines, na.strings,  :
  number of items read is not a multiple of the number of columns
Run Code Online (Sandbox Code Playgroud)

没有BOM文件导入的UTF-8:

> unicode.csv <- read.table("~/csv1a.csv", sep=";", dec=",", quote="",fileEncoding="UTF-8") #result:    failure to import all row
Warning messages:
1: In scan(file, what, nmax, sep, dec, quote, skip, nlines, na.strings,  :
  invalid input found on input connection '~/Revolution/RProject1/csv1a.csv'
2: In scan(file, what, nmax, sep, dec, quote, skip, nlines, na.strings,  :
  number of items read is not a multiple of the number of columns
Run Code Online (Sandbox Code Playgroud)

区域信息:

> Sys.getlocale()
   [1] "LC_COLLATE=English_United States.1252;LC_CTYPE=English_United States.1252;LC_MONETARY=English_United States.1252;LC_NUMERIC=C;LC_TIME=English_United States.1252"
Run Code Online (Sandbox Code Playgroud)

Windows上的R对此负责的是什么?除了放弃窗户之外,我已经尝试了所有我能做到的事情.

谢谢

(其他尝试失败):

>Sys.setlocale("LC_ALL", "en_US.UTF-8") #OS reports request to set locale to "en_US.UTF-8" cannot be honored
>options(encoding="UTF-8") #now nothing can be imported  
> noarg.unicode.csv <- read.table("~/Revolution/RProject1/csv1a.csv", sep=";", dec=",", quote="")   #result: mangled cyrillic
> encarg.unicode.csv <- read.table("~/Revolution/RProject1/csv1a.csv", sep=";", dec=",", quote="",encoding="UTF-8") #result: mangled cyrillic
Run Code Online (Sandbox Code Playgroud)

pus*_*t88 5

通过将fileEncoding更改为编码可以解决您的问题,这些参数在read函数中的工作方式不同(请参阅?read).

oem.csv <- read.table("~/csv1.csv", sep=";", dec=",", quote="",encoding="cp866")
Run Code Online (Sandbox Code Playgroud)

但是,如果有更完整的答案,因为可能存在一些非明显的障碍.简而言之:可以在Windows上使用Cyrillic in R(在我的案例中是Win 7).

您可能需要尝试一些可能的编码才能使事情发挥作用.对于文本挖掘,一个重要方面是使输入变量与数据匹配.在那里Encoding()的功能非常有用,另见iconv().因此,可以看到您的原始参数.

Encoding(variant <- "???????")
Run Code Online (Sandbox Code Playgroud)

在我的情况下,编码是UTF-8,但这可能取决于系统设置.因此,我们可以使用UTF-8和UTF-8-BOM来尝试结果,并使用拉丁语和一系列西里尔语在notepad ++中创建一个测试文件.

UTF8_nobom_cyrillic.csv和UTF8_bom_cyrillic.csv

part2, part3, part4
??????? ?????????, ????????????, ?? ???
Run Code Online (Sandbox Code Playgroud)

这可以导入到R中

raw_table1 <- read.csv("UTF8_nobom_cyrillic.csv", header = FALSE, sep = ",", quote = "\"", dec = ".", fill = TRUE, comment.char = "", encoding = "UTF-8")
raw_table2 <- read.csv("UTF8_bom_cyrillic.csv", header = FALSE, sep = ",", quote = "\"", dec = ".", fill = TRUE, comment.char = "", encoding = "UTF-8-BOM")
Run Code Online (Sandbox Code Playgroud)

这些结果对我来说是视图(raw_table1)中的BOM常规西里尔文,以及控制台中的乱码.

part2, part3, part4
ŠŠøŠ½ŠµŠ¼?м Š?онŠ??‹Šæ?‚ам ?‚?…?¨Š¾Šæ?…?€Š°Š¶?‚?Š
Run Code Online (Sandbox Code Playgroud)

但更重要的是,脚本无法访问它.

> grep("???????", as.character(raw_table2[2,1]))
integer(0)
Run Code Online (Sandbox Code Playgroud)

No BOM UTF-8的结果对于view(raw_table1)和console都是这样的.

part2, part3, part4
<U+041C><U+0438><U+043D><U+0435><U+043C><U+0443><U+043C> <U+043A><U+043E><U+043D><U+043A><U+044B><U+043F><U+0442><U+0430><U+043C> <U+0442><U+0445><U+044D><U+043E><U+043F><U+0445><U+0440><U+0430><U+0436><U+0442><U+0443><U+0437> <U+0435><U+0434> <U+043F><U+0440><U+043E>
Run Code Online (Sandbox Code Playgroud)

但是,重要的是,搜索内部单词将产生正确的结果.

> grep("???????", as.character(raw_table1[2,1]))
1
Run Code Online (Sandbox Code Playgroud)

因此,可以在Windows中使用非标准字符,具体取决于您的确切目标.我定期使用非英语拉丁字符,UTF-8允许在Windows 7中工作,没有任何问题."WINDOWS-1252"对于导出到Excel等Microsoft读者非常有用.

PS俄语单词在这里生成http://generator.lorem-ipsum.info/_russian,所以基本上没有意义.PPS你提到的警告仍然没有明显的重要影响.


use*_*636 5

简单回答.

Sys.setlocale(locale = "Russian")

如果你只想要俄语(不是格式,货币):

'Sys.setlocale(category = "LC_COLLATE", locale = "Russian")'

'Sys.setlocale(category = "LC_CTYPE", locale = "Russian")'

如果恰好使用Revolution R Open 3.2.2,您可能还需要在控制面板中设置区域设置:否则 - 如果您有RStudio - 您将在Viewer中看到西里尔文本并在控制台中看到垃圾.因此,例如,如果您键入随机的西里尔字符串并按Enter键,您将获得垃圾输出.有趣的是,Revolution R与阿拉伯语文本没有相同的问题.如果你使用常规R,似乎Sys.setlocale()就足够了.

'Sys.setlocale()'是由用户G. Grothendieck在这里建议的:R,Windows和外语字符


Ist*_*sta 5

有两个选项可用于从包含当前语言环境不支持的字符的文件中读取数据。您可以按照@ user23676的建议更改语言环境,也可以转换为UTF-8。该readr软件包read.table为您执行此转换的派生函数提供了替代。您可以使用以下命令读取CP866文件:

library(readr)
oem.csv <- read_csv2('~/csv1.csv', locale = locale(encoding = 'CP866'))
Run Code Online (Sandbox Code Playgroud)

有一个小问题,那就是存在一个错误print.data.frame,导致带有UTF-8编码的列在Windows上无法正确显示。您可以使用print.listof(oem.csv)或解决该错误print(as.matrix(oem.csv))

我已经在http://people.fas.harvard.edu/~izahn/posts/reading-data-with-non-native-encoding-in-r/中的博客文章中对此进行了更详细的讨论。


vla*_*490 5

我认为这里都有很好的答案,但也有很多重复的答案。我尝试提供更完整的问题描述以及我使用上述解决方案的方式。

\n\n

我的情况 - 将 Google Translate API 的结果写入 R 中的文件

\n\n

出于我的特定目的,我向 Google API 发送文本:

\n\n
   # load library\n   library(translateR)\n\n   # return chinese tranlation\n   result_chinese <- translate(content.vec = "This is my Text",\n                            google.api.key = api_key, \n                            source.lang = "en",\n                            target.lang = "zh-CN")\n
Run Code Online (Sandbox Code Playgroud)\n\n

我在 中看到的结果R Environment是这样的:

\n\n

R 环境中看到的翻译结果

\n\n

但是,如果我在控制台中打印我的变量,我将看到这个格式良好的(我希望)文本:

\n\n
> print(result_chinese)\n[1] "\xe8\xbf\x99\xe6\x98\xaf\xe6\x88\x91\xe7\x9a\x84\xe6\x96\x87\xe5\xad\x97"\n
Run Code Online (Sandbox Code Playgroud)\n\n

在我的情况下,我必须使用 R 函数将文件写入计算机文件系统write.table()......但我要写入的任何内容都将采用以下格式:

\n\n

R 环境中看到的翻译结果

\n\n

我的解决方案 - 取自上面的答案:

\n\n

我决定实际使用Sys.setlocale()这样的函数:

\n\n
Sys.setlocale(locale = "Chinese") # set locale to Chinese\n\n> Sys.setlocale(locale = "Chinese") # set locale to Chinese\n[1] "LC_COLLATE=Chinese (Simplified)_People\'s Republic of China.936;LC_CTYPE=Chinese (Simplified)_People\'s Republic of China.936;LC_MONETARY=Chinese (Simplified)_People\'s Republic of China.936;LC_NUMERIC=C;LC_TIME=Chinese (Simplified)_People\'s Republic of China.936"\n
Run Code Online (Sandbox Code Playgroud)\n\n

之后我的翻译在 R 环境中正确可视化:

\n\n
# return chinese tranlation with new locale \nresult_chinese <- translate(content.vec = "This is my Text",\n                            google.api.key = api_key, \n                            source.lang = "en",\n                            target.lang = "zh-CN")\n
Run Code Online (Sandbox Code Playgroud)\n\n

R环境中的结果是:

\n\n

R 环境中正确可视化的翻译

\n\n

之后我可以编写我的文件并最终看到中文文本:

\n\n
# writing \nwrite.table(result_chinese, "translation.txt")\n
Run Code Online (Sandbox Code Playgroud)\n\n

从 Notepad++ 中可以看到正确可视化和写入的文件

\n\n

最后,在我的翻译功能中,我将返回到原始设置:

\n\n
Sys.setlocale() # to set up current locale to be default of the system\n\n> Sys.setlocale() # to set up current locale to be default of the system\n[1] "LC_COLLATE=English_United Kingdom.1252;LC_CTYPE=English_United Kingdom.1252;LC_MONETARY=English_United Kingdom.1252;LC_NUMERIC=C;LC_TIME=English_United Kingdom.1252"\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的结论:

\n\n

在处理 R 中的特定语言之前:

\n\n
    \n
  1. 将区域设置设置为特定语言的区域设置 Sys.setlocale(locale = "Chinese") # set locale to Chinese
  2. \n
  3. 执行所有数据操作
  4. \n
  5. 返回到原来的设置 Sys.setlocale() # set original system settings
  6. \n
\n