【问题标题】:Quickly Write Vector to File r快速将向量写入文件 r
【发布时间】:2018-03-12 22:19:58
【问题描述】:

将向量写入文件的最快方法是什么?我有一个大约 200 万行的字符向量,并且具有相当大的值(200 个字符)。我现在在做

write(myVector, "myFile.txt")

但这非常慢。我已经四处寻找解决方案,但快速写入功能(例如fwrite)仅将数据框/矩阵作为输入。谢谢!

【问题讨论】:

  • 你可以试试readr::write_lines?或者您可以将向量设为数据框的一列

标签: r


【解决方案1】:

在尝试了几个选项后,我发现最快的是data.table::fwrite。就像@Gregor 在他的第一条评论中所说,它快了一个数量级,这值得加载额外的包。它也是产生更大文件的文件之一。 (另一个是readr::write_lines。感谢Calum You的评论,我忘记了这个。)

library(data.table)
library(readr)

set.seed(1)    # make the results reproducible
n <- 1e6
x <- rnorm(n)

t1 <- system.time({
    sink(file = "test_sink.txt")
    cat(x, "\n")
    sink()
})
t2 <- system.time({
    cat(x, "\n", file = "test_cat.txt")
})
t3 <- system.time({
    write(x, file = "test_write.txt")
})
t4 <- system.time({
    fwrite(list(x), file = "test_fwrite.txt")
})
t5 <- system.time({
    write_lines(x, "test_write_lines.txt")
})

rbind(sink = t1[1:3], cat = t2[1:3], 
      write = t3[1:3], fwrite = t4[1:3],
      readr = t5[1:3])
#       user.self sys.self elapsed
#sink        4.18    11.64   15.96
#cat         3.70     4.80    8.57
#write       3.71     4.87    8.64
#fwrite      0.42     0.02    0.51
#readr       2.37     0.03    6.66

在他的第二条评论中,Gregor 指出 as.listlist 的行为不同。区别很重要。前者将向量写入一行多列,后者写入一列多行。

速度差异也很明显:

fw1 <- system.time({
    fwrite(as.list(x), file = "test_fwrite.txt")
})
fw2 <- system.time({
    fwrite(list(x), file = "test_fwrite2.txt")
})

rbind(as.list = fw1[1:3], list = fw2[1:3])
#        user.self sys.self elapsed
#as.list      0.67     0.00    0.75
#list         0.19     0.03    0.11

最后清理。

unlink(c("test_sink.txt", "test_cat.txt", "test_write.txt",
         "test_fwrite.txt", "test_fwrite2.txt", "test_write_lines.txt"))

【讨论】:

  • 也许值得在第一句话中指出,fwrite 不仅最快,而且快了 10 倍以上。 readrwritecat 快,但只是略微。
  • 另外,您的fwrite 代码不正确,您需要list(x) 而不是as.list(x)as.list() 将编写一个包含一行和 n 列的 CSV(并且会慢一点)。 list(x) 将给出 n 行和 1 列。
  • @GregorThomas 感谢list()as.list() 的注意!
【解决方案2】:

我发现writeBin 的速度是fwrite 的两倍。试试这个:

 zz <- file("myFile.txt", "wb")
 writeBin( paste(myVector, collapse="\n"), zz ) 
  close(zz)

使用我得到的 Rui 提供的相同计时方法(旧框):

            user.self sys.self elapsed
sink            9.650    7.900  17.418
cat             6.507    7.870  14.254
write           6.436    7.849  14.171
fwrite          0.500    0.051   0.593
write_lines     4.337    0.150   4.451
writeBin        0.238    0.006   0.242 

【讨论】:

    【解决方案3】:

    你可以使用data.table的fwrite:

    library(data.table) # install if not installed already
    fwrite(list(myVector), file = "myFile.csv")
    

    【讨论】:

    • 由于 OP 有一个向量,而不是一个列表或数据框,你需要fwrite(list(myVector), "myFile.csv")
    猜你喜欢
    • 2021-03-20
    • 2015-01-27
    • 2017-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-09
    • 2011-06-25
    • 1970-01-01
    相关资源
    最近更新 更多