使用UTF-16编码的R写入csv

12

我在使用 write.csv 时遇到了问题,希望能够使用 UTF-16 字符编码输出一个数据框。

背景:我正在尝试从数据框中写出一个 CSV 文件,以供 Excel 使用。Excel Mac 2011似乎不喜欢UTF-8(如果我在文本导入期间指定UTF-8,则非ASCII字符将显示为下划线)。我被告知Excel将使用UTF-16LE编码。

以下是示例数据框:

> foo
  a  b
1 á 羽
> Encoding(levels(foo$a))
[1] "UTF-8"
> Encoding(levels(foo$b))
[1] "UTF-8"

所以我尝试通过以下方式输出数据框:

f <- file("foo.csv", encoding="UTF-16LE")
write.csv(foo, f)
这给了我一个看起来像ASCII文件的东西:
"","
如果我使用encoding="UTF-16",我得到的文件只包含字节顺序标记0xFE 0xFF
如果我使用encoding="UTF-16BE",我得到一个空文件。
这是在Mac OS X 10.6.6上运行的64位版本的R 2.12.2。 我做错了什么?

2
说实话,Excel和UTF-8出了什么问题?我是说,现在都2011年了。 - Daniel Dickison
2个回答

7

您可以将csv文件保存为UTF-8格式,然后在终端中使用iconv将其转换为UTF-16LE格式。

如果您坚持要在R中进行操作,以下方法可能有效 - 尽管似乎R中的iconv存在一些问题,请参见:http://tolstoy.newcastle.edu.au/R/e10/devel/10/06/0648.html

> x <- c("foo", "bar")
> iconv(x,"UTF-8","UTF-16LE")
Error in iconv(x, "UTF-8", "UTF-16LE") : 
  embedded nul in string: 'f\0o\0o\0'

正如您所看到的,上面链接的补丁确实是必要的。虽然我没有测试过,但如果您想保持简单(且不太好):在将表保存为 csv 后,仅需使用 system 调用 R 内的第三方 iconv 程序即可。


我在输出UTF-8后使用了iconv,但我希望我只是做错了什么,R可以直接输出UTF-16。我想这可能不是情况... - Daniel Dickison
1
@Daniel Dickison:看起来是这样的:( 如果可以的话,我建议您在保存数据框后从R中调用iconv,只需使用system函数-这样您就不必启动单独的程序。您还可以编写一个小函数自动化该过程,该函数保存csv并将其转换为所需的编码。无论如何祝你好运! - daroczig
1
为什么在R中UTF-16 iconv问题仍未得到解决(该补丁的日期为2010年)?在2016年,我仍然看不到在R中读取或写入UTF-16(Windows)编码文本文件的简便“本地”方式 :-( - R Yoda

4

类似这样的操作可能有用(write.csv() 简单地忽略了编码,因此您需要选择 writLines()writeBin())...

#' function to convert character vectors to UTF-8 encoding
#'
#' @param x the vector to be converted
#' @export 

toUTF8 <- 
  function(x){
    worker <- function(x){
      iconv(x, from = Encoding(x), to = "UTF-8")
    }
    unlist(lapply(x, worker))
  }



#' function to write csv files with UTF-8 characters (even under Windwos)
#' @param df data frame to be written to file
#' @param file file name / path where to put the data
#' @export 

write_utf8_csv <- 
function(df, file){
  firstline <- paste(  '"', names(df), '"', sep = "", collapse = " , ")
  char_columns <- seq_along(df[1,])[sapply(df, class)=="character"]
  for( i in  char_columns){
    df[,i] <- toUTF8(df[,i])
  }
  data <- apply(df, 1, function(x){paste('"', x,'"', sep = "",collapse = " , ")})
  writeLines( c(firstline, data), file , useBytes = T)
}


#' function to read csv file with UTF-8 characters (even under Windwos) that 
#' were created by write_U
#' @param df data frame to be written to file
#' @param file file name / path where to put the data
#' @export 

read_utf8_csv <- function(file){
  # reading data from file
  content <- readLines(file, encoding = "UTF-8")
  # extracting data
  content <- stringr::str_split(content, " , ")
  content <- lapply(content, stringr::str_replace_all, '"', "")
  content_names <- content[[1]][content[[1]]!=""]
  content <- content[seq_along(content)[-1]]  
  # putting it into data.frame
  df <- data.frame(dummy=seq_along(content), stringsAsFactors = F)
  for(name in content_names){
    tmp <- sapply(content, `[[`, dim(df)[2])
    Encoding(tmp) <- "UTF-8"
    df[,name] <- tmp 
  }
  df <- df[,-1]
  # return
  return(df)
}

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