cat()和sprintf()的替代方法可以在文件中更快地写入输出

时间:2017-10-31 01:45:03

标签: r connected-components

我是R的新手,预处理了数百万行的大数据,以标记连接的组件并将输出发送到文件。但是使用for循环和cat()需要花费大量的时间。有没有其他方法在R中以更快的方式写输出文件?我正在分享一些代码示例。任何替代方法或使用使其更有效的功能重写它将受到高度赞赏。

#Simple example of undirected graph
g <- graph_from_literal(a--b, a--c, b--c, d--e)
plot(g)

#Connected components
#The option, mode, is ignored for undirected graphs
comp <- components(g, mode = "weak")

#output to a file
fout <- file("output.txt", "w")
for (v in V(g)) {

  vn <- V(g)$name[v]
  comp_id <- comp$membership[vn][[1]]
  comp_size <- comp$csize[comp_id]
  cat(sprintf("%s\t%s\t%s\n", vn, comp_id, comp_size), file=fout)

}

close(fout)

3 个答案:

答案 0 :(得分:1)

似乎所有内容都是矢量化的,并且不需要for循环。这会提供相同的输出并使用data.table::fwrite,这将比cat快一点。

vv = V(g)
vn = vv$name
comp_id = comp$membership[vv$name]
comp_size = comp$csize[comp_id]
data.table::fwrite(data.table(vn, comp_id, comp_size), "output.txt", col.names = FALSE, sep = "\t")

如果你不想要数据表依赖,你可以使用base::write.table,这仍然比自己用标签粘贴字符串更好。

答案 1 :(得分:1)

我遇到了类似的问题,即如何将 3 百万(短)行写入文本文件。我发现使用 writeChar 可以加速文件写入过程(从几分钟到几秒)。

下面,我将您代码中的 cat 替换为 writeChar

g <- graph_from_literal(a--b, a--c, b--c, d--e)
plot(g)

#Connected components
#The option, mode, is ignored for undirected graphs
comp <- components(g, mode = "weak")


# first clean the file if it exists
fout <- file("output.txt", "wb")
close(fout)

# switch in appending mode
fout <- file("output.txt", "ab")

for (v in V(g)) {
  
  vn <- V(g)$name[v]
  comp_id <- comp$membership[vn][[1]]
  comp_size <- comp$csize[comp_id]
  # set eos = NULL to avoid NULL terminators
  writeChar(sprintf("%s\t%s\t%s\n", vn, comp_id, comp_size), con = fout, eos = NULL)
}

close(fout)

答案 2 :(得分:0)

(警告:我没有你的任何数据,所以这是未经测试的。)

而不是在循环中每次,而是生成字符串的向量(每个文件行一个)并在结尾写一次。这种类型的文件I / O效率更高。

all_lines <- sapply(V(g), function(v) {
  vn <- V(g)$name[v]
  comp_id <- comp$membership[vn][[1]]
  comp_size <- comp$csize[comp_id]
  sprintf("%s\t%s\t%s\n", vn, comp_id, comp_size)
})
writeLines(all_lines, "output.txt")

使用sapply是R的一种效率,做事情的事情和#34;。虽然这不是绝对必要的(这可以通过for循环完成,但需要采取一些预防措施,以使非常低效,特别是在处理一百万行时,一旦可以&#34; grok&#34;理解和处理矢量力学的意图。