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

Posted

技术标签:

【中文标题】在 R 中将 UTF-8 BOM 导出为 .csv【英文标题】:Export UTF-8 BOM to .csv in R 【发布时间】:2011-11-16 04:02:54 【问题描述】:

我正在通过 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)

【问题讨论】:

你是说打开导出的文件时看到的是“U+0436”而不是“ж”?如果是这样,那不是 BOM 问题,只是 Unicode 代码点没有被编码为 UTF 编码,而是作为代码点输出的问题。也许向我们展示一些代码,您究竟是如何导出文件的? 我添加了有关如何导出文件的信息。是的,我看到的是“”而不是“ж” 在文件中看到“”是模棱两可的(甚至可能意味着这些字符实际上已内联在该文件中,或者您的编辑器无法显示它们)。您可以在文件中写下“ж”并告诉我们生成的文件包含的所有字符的十六进制值(在十六进制编辑器中打开);或者给我们代码来重现你的问题(当然我们没有你的数据库,所以用示例数据创建一个向量)。 【参考方案1】:

接受的答案在类似的应用程序中对我没有帮助(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 文件的路径。

【讨论】:

这很棒。这应该是公认的答案(Windows 7,R 版本 3.4.2) 在 R 3.5.3 上仍然运行良好。只是两个小评论:您可以只使用on.exit(close(con)),而不是tryCatch() 构造。将fileEncoding = "utf-8" 传递给write.csv() 以获得最佳效果也可能很有用。【参考方案2】:

Encoding (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)

【讨论】:

以上是关于在 R 中将 UTF-8 BOM 导出为 .csv的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 中将带 BOM 的 UTF-8 转换为不带 BOM 的 UTF-8

通过PHP导出CSV以获取utf-8字符

php 导出excle的.csv格式的数据时乱码问题

哪种编码可以在 Mac 和 Windows 上使用 Excel 正确打开 CSV 文件?

在 Rails 中将 2 个表导出为 CSV [如何选择特定列?]

如何:在 MySQL 工作台中将记录集导出为分号分隔的 csv 文件?