在R中将UTF-8 BOM导出为.csv文件

11

我正在通过RJDBC从MySQL数据库读取文件,并且在R中正确显示所有字母(例如,נווה שאנן)。 然而,即使使用write.csv和fileEncoding="UTF-8"导出,输出看起来像是 <U+0436>.<U+043A>. <U+041B><U+043E><U+0437><U+0435><U+043D><U+0435><U+0446>(在这种情况下,这不是上面的字符串,而是保加利亚语)。对于像ã、ç等其他特殊字符,工作正常。

我怀疑这是由于UTF-8 BOM,但我在网上没有找到解决方案。

我的操作系统是德国Windows7。

编辑:

con<-file("file.csv",encoding="UTF-8")
write.csv(x,con,row.names=FALSE)

而且 (afaik) 等价于 write.csv(x, file="file.csv",fileEncoding="UTF-8",row.names=FALSE)


3
你的意思是当你打开导出的文件时,看到的是“U+0436”而不是“ж”吗?如果是这样,那么这不是BOM的问题,只是Unicode代码点没有被编码成UTF编码,而是以代码点输出的问题。可以展示一下你导出文件的代码吗? - deceze
我添加了有关如何导出文件的信息。是的,我看到"<U+0436>"而不是"ж"。 - Arthur G
1
在文件中看到"<U+0436>"是不明确的(它甚至可能意味着这些字符实际上是内嵌在该文件中,或者您的编辑器只是无法显示它们)。您可以在文件中写入"ж"并告诉我们生成文件包含的所有字符的十六进制值(在十六进制编辑器中打开它);或者给我们提供重现问题的代码(当然我们没有您的数据库,因此请使用示例数据创建一个向量)。 - Bernd Elkemann
2个回答

11

对于类似的应用程序(在Windows中使用R 3.1,尝试在Excel中打开文件),被接受的答案没有帮助我。不过,基于file文档的这一部分:

如果需要BOM(不建议使用),在写入时应显式地写入,例如通过writeChar("\ufeff",con,eos = NULL)或writeBin(as.raw(c(0xef,0xbb,0xbf)),binary_con)

我想出了以下解决方法:

write.csv.utf8.BOM <- function(df, filename)
{
    con <- file(filename, "w")
    tryCatch({
    for (i in 1:ncol(df))
        df[,i] = iconv(df[,i], to = "UTF-8") 
    writeChar(iconv("\ufeff", to = "UTF-8"), con, eos = NULL)
    write.csv(df, file = con)
    },finally = {close(con)})
}

请注意,df 是数据框(data.frame),filename 是CSV文件的路径。


2
这太棒了。这应该是被接受的答案(Windows 7,R版本3.4.2)。 - TaylorV
2
仍然在 R 3.5.3 上运行良好。只有两个小备注:您可以使用 on.exit(close(con)) 替代 tryCatch() 结构。对于最佳结果,将 fileEncoding = "utf-8" 传递给 write.csv() 可能也很有用。 - Stefan F

6

help("Encoding")的帮助页面中,您可以了解特殊编码方式-bytes

使用此方法,我成功生成了csv文件:

v <- "נווה שאנן"
X <- data.frame(v1=rep(v,3), v2=LETTERS[1:3], v3=0, stringsAsFactors=FALSE)

Encoding(X$v1) <- "bytes"
write.csv(X, "test.csv", row.names=FALSE)

请注意factorcharacter之间的区别。以下内容应该有效:

id_characters <- which(sapply(X,
    function(x) is.character(x) && Encoding(x)=="UTF-8"))
for (i in id_characters) Encoding(X[[i]]) <- "bytes"

id_factors <- which(sapply(X,
    function(x) is.factor(x) && Encoding(levels(x))=="UTF-8"))
for (i in id_factors) Encoding(levels(X[[i]])) <- "bytes"

write.csv(X, "test.csv", row.names=FALSE)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接