To moja realizacja idei, że @Bill Denney zasugerował. Myślę, że jest ładniejszy częściowo dlatego, że jest krótsza i bardziej zrozumiałe dla mnie, ale głównie dlatego, że napisał ją :)
##' Write CSV files with quotes same as MS Excel 2013 or newer
##'
##' R inserts quotes where MS EExcel CSV export no longer inserts quotation marks on character
##' variables, except when the cells include commas or quotation marks.
##' This function generates CSV files that are, so far as we know
##' in exactly the same style as MS Excel CSV export files.
##'
##' This works by manually inserting quotation marks where necessary and
##' turning FALSE R's own method to insert quotation marks.
##' @param x a data frame
##' @param file character string for file name
##' @param row.names Default FALSE for row.names
##' @return the return from write.table.
##' @author Paul Johnson
##' @examples
##' set.seed(234)
##' x1 <- data.frame(x1 = c("a", "b,c", "b", "The \"Washington, DC\""),
##' x2 = rnorm(4), stringsAsFactors = FALSE)
##' x1
##' dn <- tempdir()
##' fn <- tempfile(pattern = "testcsv", fileext = ".csv")
##' writeCSV(x1, file = fn)
##' readLines(fn)
##' x2 <- read.table(fn, sep = ",", header = TRUE, stringsAsFactors = FALSE)
##' all.equal(x1,x2)
writeCSV <- function(x, file, row.names = FALSE){
xischar <- colnames(x)[sapply(x, is.character)]
for(jj in xischar){
x[ , jj] <- gsub('"', '""', x[ , jj], fixed = TRUE)
needsquotes <- grep('[\",]', x[ ,jj])
x[needsquotes, jj] <- paste0("\"", x[needsquotes, jj], "\"")
}
write.table(x, file = file, sep = ",", quote = FALSE,
row.names = row.names)
}
Wyjście z przykładu:
> set.seed(234)
> x1 <- data.frame(x1 = c("a", "b,c", "b", "The \"Washington, DC\""),
+ x2 = rnorm(4), stringsAsFactors = FALSE)
> x1
x1 x2
1 a 0.6607697
2 b,c -2.0529830
3 b -1.4992061
4 The "Washington, DC" 1.4712331
> dn <- tempdir()
> fn <- tempfile(pattern = "testcsv", fileext = ".csv")
> writeCSV(x1, file = fn)
> readLines(fn)
[1] "x1,x2"
[2] "a,0.660769736644892"
[3] "\"b,c\",-2.052983003941"
[4] "b,-1.49920605110092"
[5] "\"The \"\"Washington, DC\"\"\",1.4712331168047"
> x2 <- read.table(fn, sep = ",", header = TRUE, stringsAsFactors = FALSE)
> all.equal(x1,x2)
[1] TRUE
>
[Docs] (http://stat.ethz.ch/R-manual/R-devel/library/utils/html/write.table.html) wydają się mówić, że nie jest to możliwe, chyba że wiesz z góry, które kolumny cytować ("Jeśli [. quote' is] to wektor liczbowy, jego elementy są traktowane jako wskaźniki kolumn do cytowania. "). Inne języki oferują opcję "cytuj tylko wtedy, gdy jest to konieczne", której R wydaje się nie mieć. Być może mógłbyś postprocesować swoje pliki w takim języku (jak Python)? –
lub coś w stylu 'który (sapply (mydata, funkcja (x) (is.factor (x) || is.character (x)) && any (grepl (", "x)))', aby dowiedzieć się, które kolumny potrzebują być chronionym? –
@TimPietzcker Podczas przeglądania, wygląda na to, że nie ma wbudowanego sposobu cytowania w razie potrzeby, ale użyłem twoich sugestii, aby zacytować tylko kolumny, których to dotyczy. "Jeśli któryś z was chce napisać jako odpowiedź, Przyjmij to. – James