这是上一个 Stack Overflow 问题的延续:
Fastest way to read in 100,000 .dat.gz files
我有很多 .dat.gz 文件,但是这个数据中的许多行都有零值,我想避免将它们带入内存。
为测试用例创建数据:
# Make dir
system("mkdir practice")
require(data.table)
# Function to create data
create_write_data <- function(file.nm) {
dt <- data.table(Day=0:365)
dt[, (paste0("V", 1:17)) := lapply(1:17, function(x) rpois(n=366, 0.1))]
write.table(dt, paste0("./practice/",file.nm), row.names=FALSE, sep="\t", quote=FALSE)
system(paste0("gzip ./practice/", file.nm))
}
这是应用代码:
# Apply function to create 10 fake zipped data.frames (550 kb on disk)
tmp <- lapply(paste0("dt", 1:10,".dat"), function(x) create_write_data(x))
我的解决方案(不起作用)
之前链接的 Stack Overflow 答案给出了一次读取所有数据的好答案:
tbl = fread('cat ./practice/*dat.gz | gunzip | grep -v "^Day"')
但是现在我想过滤第 14 列和第 15 列都不为 0 的数据,因此我创建了以下管道以提供给
fread
使用 awk
命令:command <- "cat ./practice/*dat.gz | gunzip | awk -F, '!/^Day/ && $14 !=0 && $15 != 0'"
fread(command)
但是,这根本没有过滤我的数据。关于如何让 awk 命令在此工作流程中工作的任何想法?
最佳答案
这个问题在评论中得到了答案。
好的..它似乎适用于以下内容:
command <- "cat ./practice/*dat.gz | gunzip | awk -F, '!/^Day/' | awk '$14 != 0 || $15 != 0'"
这是对数据进行 2 次传递吗?看起来它可能会减慢许多文件的速度,但它似乎确实有效。
不,这不是 2 次数据传递。它的效率很高。但是之前错过了另一个小优化:可以进一步简化为 gunzip -c ./path/to/files*.dat.gz | awk
...
关于r - 使用 fread 和 awk 子集许多 .dat.gz 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36680417/