R write.csv с кодировкой UTF-16 - PullRequest
12 голосов
/ 11 марта 2011

У меня проблемы с выводом data.frame с использованием write.csv с использованием кодировки символов UTF-16.

Справочная информация: я пытаюсь записать файл CSV из data.frame для использования в Excel,Excel Mac 2011, похоже, не любит UTF-8 (если я укажу UTF-8 во время импорта текста, символы, не входящие в ASCII, будут отображаться в виде подчеркивания).Меня убеждают, что Excel будет доволен кодировкой UTF-16LE.

Вот пример data.frame:

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

Поэтому я попытался вывести data.frame с помощьюделать:

f <- file("foo.csv", encoding="UTF-16LE")
write.csv(foo, f)

Это дает мне файл ASCII, который выглядит следующим образом:

"","

Если я использую encoding="UTF-16", я получаю файл, который содержит только метку порядка байтов 0xFE 0xFF.

Если я использую encoding="UTF-16BE", я получаю пустой файл.

Это на 64-битной версии R 2.12.2 в Mac OS X 10.6.6.Что я делаю не так?

Ответы [ 2 ]

7 голосов
/ 11 марта 2011

Вы можете просто сохранить csv в UTF-8 и затем преобразовать его в UTF-16LE с помощью iconv в терминале.

Если вы настаиваете на том, чтобы делать это в R, может сработать следующее - хотя кажется, что у iconv в R есть некоторые проблемы, см .: 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'

Как вы можете видеть, вышеупомянутый связанный патч действительно нужен - который я не тестировал, но если вы хотите сохранить его простым (и неприятным): просто вызовите стороннюю программу iconv внутри R с вызовом system после сохранение таблицы в csv .

4 голосов
/ 05 мая 2015

может сработать что-то подобное (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)
}
...