从列表转换为R中的data.frame时,utf-8字符会丢失

jir*_*ec2 7 locale r utf-8 character-encoding dataframe

我在Windows 7 64位上使用R 3.2.0和RStudio 0.98.1103.我的电脑的Windows"区域和语言设置"是英语(美国).

出于某种原因,下面的代码在文本"Koryčanynadpřehradou"中用"c"和"r"替换了我的捷克字符"č"和"ř",当我从网上读取utf-8编码的XML文件时,解析XML文件到列表,并将列表转换为data.frame.

library(XML)
url <- "http://hydrodata.info/chmi-h/cuahsi_1_1.asmx/GetSiteInfoObject?site=CHMI-H:1263&authToken="
doc <- xmlRoot(xmlTreeParse(url, getDTD=FALSE, useInternalNodes = TRUE))
infoList <- xmlToList(doc[[2]][[1]])
siteName <- infoList$siteName

#this still displays correctly "Kory?any nad p?ehradou"
print(siteName) 

#make a data.frame from the list item. I suspect here is the problem.
df <- data.frame(name=siteName, id=1)

#now the Czech characters are lost. I see only "Korycany nad prehradou"
View(df) 

write.csv(df,"test.csv")
#the test.csv file also contains "Korycany nad prehradou" 
#instead of "Kory?any nad p?ehradou"
Run Code Online (Sandbox Code Playgroud)

问题是什么?如何让R使用所有utf-8特殊字符正确显示我的data.frame并保存.csv文件而不会丢失"č"和"ř"捷克字符?

jir*_*ec2 4

这不是一个完美的答案,但以下解决方法为我解决了问题。我试图理解 R 的行为,并制作示例,以便我的 R 脚本在 Windows 和 Linux 平台上产生相同的结果:

\n\n

(1) 从网上获取UTF-8格式的XML数据

\n\n
library(XML)\nurl <- "http://hydrodata.info/chmi-h/cuahsi_1_1.asmx/GetSiteInfoObject?site=CHMI-H:1263&authToken="\ndoc <- xmlRoot(xmlTreeParse(url, getDTD=FALSE, useInternalNodes = TRUE))\ninfoList <- xmlToList(doc[[2]][[1]])\nsiteName <- infoList$siteName\n
Run Code Online (Sandbox Code Playgroud)\n\n

(2) 从网上打印出文本:编码为UTF-8,在Windows上使用捷克语和英语语言环境在R控制台中显示也是正确的:

\n\n
> Sys.getlocale(category="LC_CTYPE")\n[1] "English_United States.1252"\n> print(siteName)\n[1] "Kory\xc4\x8dany nad p\xc5\x99ehradou"\n> Encoding(siteName)\n[1] "UTF-8"\n> \n
Run Code Online (Sandbox Code Playgroud)\n\n

(3) 尝试创建并查看一个data.frame。这有一个问题。data.frame 在 RStudio 视图和控制台中显示不正确:

\n\n
df <- data.frame(name=siteName, id=1)\ndf\n                    name id\n1 Korycany nad prehradou  1\n
Run Code Online (Sandbox Code Playgroud)\n\n

(4)尝试用矩阵代替。令人惊讶的是,矩阵在 R 控制台中正确显示。

\n\n
m <- as.matrix(df)\nView(m)  #this shows incorrectly in RStudio\nm        #however, this shows correctly in the R console.\n     name                     id \n[1,] "Kory\xc4\x8dany nad p\xc5\x99ehradou" "1"\n
Run Code Online (Sandbox Code Playgroud)\n\n

(5) 更改区域设置。如果我使用的是 Windows,请将区域设置设置为捷克语。如果我使用的是 Unix 或 Mac,请将区域设置设置为 UTF-8。注意:当我在 RStudio 中运行脚本时,这会出现一些问题,显然 RStudio 并不总是立即对 Sys.setlocale 命令做出反应。

\n\n
#remember the original locale.\noriginal.locale <- Sys.getlocale(category="LC_CTYPE")\n\n#for Windows set locale to Czech. Otherwise set locale to UTF-8\nnew.locale <- ifelse(.Platform$OS.type=="windows", "Czech_Czech Republic.1250", "en_US.UTF-8")\nSys.setlocale("LC_CTYPE", new.locale) \n
Run Code Online (Sandbox Code Playgroud)\n\n

(7) 将数据写入文本文件。重要提示:不要使用write.csv而是使用write.table. 当我的语言环境Czech位于英语 Windows 上时,我必须fileEncoding="UTF-8"使用write.table. 现在,文本文件可以在 notepad++ 和 Excel 中正确显示。

\n\n
write.table(m, "test-czech-utf8.txt", sep="\\t", fileEncoding="UTF-8")\n
Run Code Online (Sandbox Code Playgroud)\n\n

(8) 将语言环境设置回原来的语言环境

\n\n
Sys.setlocale("LC_CTYPE", original.locale)\n
Run Code Online (Sandbox Code Playgroud)\n\n

(9) 尝试将文本文件读回 R。注意:如果我读取该文件,我必须设置参数encoding(而不是 fileEncoding!)。从文件中读取的 data.frame 的显示仍然不正确,但是当我将其转换data.framematrix捷克语 UTF-8 字符时,会保留:

\n\n
data.from.file <- read.table("test-czech-utf8.txt", sep="\\t", encoding="UTF-8")\n#the data.frame still has the display problem, "\xc4\x8d" and "\xc5\x99" get "lost"\n> data.from.file\n                     name id\n1 Korycany nad prehradou  1\n\n#see if a matrix displays correctly: YES it does!\nmatrix.from.file <- as.matrix(data.from.file)\n> matrix.from.file\n  name                     id \n1 "Kory\xc4\x8dany nad p\xc5\x99ehradou" "1"\n
Run Code Online (Sandbox Code Playgroud)\n\n

因此,吸取的教训是,在将包含捷克语字符的数据写入文件之前,我需要将 my 转换data.frame为 a matrix,将区域设置设置为Czech(在 Windows 上)或(在 Mac 和 Linux 上)。UTF-8然后当我写入文件时,我必须确保fileEncoding必须设置为UTF-8。另一方面,当我稍后阅读该文件时,我可以继续在英语语言环境中工作,但read.table我必须将encoding="UTF-8".

\n\n

如果有人有更好的解决方案,我将欢迎您的建议。

\n