使用 fread 和 awk 对许多 .dat.gz 文件进行子集化
Subsetting many .dat.gz files using fread and awk
这是上一个 Stack Overflow 问题的延续:
我有很多 .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 的数据,因此我创建了以下管道以使用 awk
命令提供给 fread
:
command <- "cat ./practice/*dat.gz | gunzip | awk -F, '!/^Day/ && !=0 && != 0'"
fread(command)
但是,这根本没有过滤我的数据。关于如何让 awk 命令在此工作流程中工作的任何想法?
这个问题在评论中得到了回答。
好的..它似乎适用于以下内容:
command <- "cat ./practice/*dat.gz | gunzip | awk -F, '!/^Day/' | awk ' != 0 || != 0'"
这是对数据进行 2 次传递吗?看起来它可能会减慢很多文件的速度,但它似乎确实有效。
不,这不是 2 次传递数据。它的效率很高。但是之前错过了另一个小优化:你可以进一步简化为 gunzip -c ./path/to/files*.dat.gz | awk
...
这是上一个 Stack Overflow 问题的延续:
我有很多 .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 的数据,因此我创建了以下管道以使用 awk
命令提供给 fread
:
command <- "cat ./practice/*dat.gz | gunzip | awk -F, '!/^Day/ && !=0 && != 0'"
fread(command)
但是,这根本没有过滤我的数据。关于如何让 awk 命令在此工作流程中工作的任何想法?
这个问题在评论中得到了回答。
好的..它似乎适用于以下内容:
command <- "cat ./practice/*dat.gz | gunzip | awk -F, '!/^Day/' | awk ' != 0 || != 0'"
这是对数据进行 2 次传递吗?看起来它可能会减慢很多文件的速度,但它似乎确实有效。
不,这不是 2 次传递数据。它的效率很高。但是之前错过了另一个小优化:你可以进一步简化为 gunzip -c ./path/to/files*.dat.gz | awk
...