替代 cat() 和 sprintf() 以更快地将输出写入文件
Alternative of cat() and sprintf() to write output faster in a file
我是 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)
(注意买者:我没有你的任何数据,所以这是未经测试的。)
不要在循环中每次 写入,而是生成一个字符串向量(每个一个文件行)并在最后写入一次。这种类型的文件 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 的一种效率,就像 "vectors of things" 一样。虽然这不是绝对必要的(这可以通过 for
循环来完成,但需要采取一些预防措施才能 而不是 非常低效,尤其是在处理百万行),一旦可以 "grok" 矢量力学的意图,它可能会变得更容易理解和处理。
似乎一切都被向量化了,不需要 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")
如果您不想要数据 table 依赖项,您可以使用 base::write.table
,这仍然比您自己将带有制表符的字符串粘贴在一起更好。
我遇到了类似的问题,即如何将 300 万(短)行写入文本文件。我发现使用 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)
我是 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)
(注意买者:我没有你的任何数据,所以这是未经测试的。)
不要在循环中每次 写入,而是生成一个字符串向量(每个一个文件行)并在最后写入一次。这种类型的文件 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 的一种效率,就像 "vectors of things" 一样。虽然这不是绝对必要的(这可以通过 for
循环来完成,但需要采取一些预防措施才能 而不是 非常低效,尤其是在处理百万行),一旦可以 "grok" 矢量力学的意图,它可能会变得更容易理解和处理。
似乎一切都被向量化了,不需要 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")
如果您不想要数据 table 依赖项,您可以使用 base::write.table
,这仍然比您自己将带有制表符的字符串粘贴在一起更好。
我遇到了类似的问题,即如何将 300 万(短)行写入文本文件。我发现使用 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)