使用fread和awk设置许多.dat.gz文件

时间:2016-04-17 18:23:03

标签: r awk data.table fread

这是此前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命令在此工作流程中工作的任何想法吗?

1 个答案:

答案 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 ...