【问题标题】:How to use readr::write_delim() to write a .csv enclosed如何使用 readr::write_delim() 写入包含的 .csv
【发布时间】:2020-01-14 15:26:44
【问题描述】:

我正在尝试使用 write_delim 在 S3 中构建一个文件,我希望它用双引号 (") 括起来,但是我不知道它是否不是 write_delim 函数中的参数,我将需要使用基本 R 函数或者如果我做错了。这是我尝试过的

s3write_using(file_filtered,
              FUN = write_delim,
              delim = ",",
              na = "",
              object = paste0(output_path,
                              "file-",
                              lubridate::today(),
                              ".csv"),
              bucket = input_bucket)

s3write_using(file_filtered,
              FUN = write_delim,
              delim = ",",
              na = "",
              quote = "double",
              object = paste0(output_path,
                              "file-",
                              lubridate::today(),
                              ".csv"),
              bucket = input_bucket)



【问题讨论】:

  • s3write_using 来自哪里?
  • 是 aws.s3 包中的一个函数

标签: r readr


【解决方案1】:

如果我对您的理解正确,您希望将 csv 写入您的 S3 存储桶,其中包括开头的一个引号和结尾的一个引号。

来自 s3write_using 文档:

FUN:对于 s3write_using,一个函数,其中 x 和文件路径将是 通过(按此顺序)。

因此,您只需定义一个函数,该函数将 R 对象作为其第一个参数,并将引号括起来的 csv 字符串写入作为第二个参数传递的路径。

如果你真的担心优化问题,readr::write_delim 肯定比write.csv 快,但是data.table 库有一个更快的函数fwrite,它允许以与write.csv 相同的方式引用

write_quoted_csv <- function(object, path)
{
  data.table::setDT(object)
  data.table::fwrite(object, path, quote = TRUE)
  data.table::setDF(object)
}

让我们使用具有 100,000 行的数据框针对 write_delim 对其进行测试:

df <- data.frame(a = 1:50000, 
                 b = 50001:100000, 
                 c = rep(LETTERS[1:10], each = 5000))

microbenchmark::microbenchmark(
  readr      = readr::write_delim(df, "~/test_readr.csv", delim = ",", na = ""),
  data.table = write_quoted_csv(df, "~/test_datatable.csv"), 
  times      = 100)
# Unit: milliseconds
#        expr       min       lq      mean    median        uq       max neval
#       readr 244.87593 257.6236 276.91877 262.86998 283.07285 416.79254   100
#  data.table  20.80768  22.8940  26.25808  24.92915  27.69624  54.55789   100

可以看到 data.table 方法快了 10 倍以上。即使这样,write_delim 也不会加上引号,而 fwrite 会:

cat(readLines("~/test_readr.csv", 10), sep = "\n")
#> a,b,c
#> 1,50001,A
#> 2,50002,A
#> 3,50003,A
#> 4,50004,A
#> 5,50005,A
#> 6,50006,A
#> 7,50007,A
#> 8,50008,A
#> 9,50009,A
cat(readLines("~/test_datatable.csv", 10), sep = "\n")
#> "a","b","c"
#> 1,50001,"A"
#> 2,50002,"A"
#> 3,50003,"A"
#> 4,50004,"A"
#> 5,50005,"A"
#> 6,50006,"A"
#> 7,50007,"A"
#> 8,50008,"A"
#> 9,50009,"A"

所以,通过一个超快速的方法,你可以这样写你的 s3 文件:

s3write_using(file_filtered,
              FUN = write_quoted_csv,
              object = paste0(output_path, "file-", lubridate::today(), ".csv"),
              bucket = input_bucket)

【讨论】:

  • 这个想法是像我们可以使用函数 write.csv(quote = TRUE) 那样包含字符串,但我无法使用 write_csv 来做到这一点。由于优化问题,我想使用 write_csv。
  • @JoseS.Ameijeiras 我已经更新了我的答案,给你一个非常有效的解决方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-30
  • 2020-04-13
  • 1970-01-01
  • 2016-11-03
  • 1970-01-01
  • 2011-12-26
相关资源
最近更新 更多