这是此前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命令在此工作流程中工作的任何想法吗?
答案 0 :(得分:0)
这个问题在评论中得到了回答。
好的..似乎可以使用以下内容:
command <- "cat ./practice/*dat.gz | gunzip | awk -F, '!/^Day/' | awk '$14 != 0 || $15 != 0'"
这是否需要2次传递数据?似乎它可能会减慢许多文件的速度,但它似乎确实有效。
不,这不是2传递数据。它&#39;很有效率。但之前错过了另一个小优化:您可以进一步简化为gunzip -c ./path/to/files*.dat.gz | awk
...