我有几十万个非常小的.dat.gz
文件,我想以最有效的方式读入R。我在文件中读取然后立即聚合并丢弃数据,因此我不担心在接近流程结束时管理内存。我真的想加快瓶颈,这恰好是解压缩和读取数据。
每个数据集由366行和17列组成。以下是我目前所做工作的可重复示例:
构建可重现的数据:
require(data.table)
# Make dir
system("mkdir practice")
# 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) rnorm(n=366))]
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))
到目前为止,这是我阅读数据时最有效的代码:
# Function to read in files as fast as possible
read_Fast <- function(path.gz) {
system(paste0("gzip -d ", path.gz)) # Unzip file
path.dat <- gsub(".gz", "", path.gz)
dat_run <- fread(path.dat)
}
# Apply above function
dat.files <- list.files(path="./practice", full.names = TRUE)
system.time(dat.list <- rbindlist(lapply(dat.files, read_Fast), fill=TRUE))
dat.list
我已将其装入一个函数并将其并行应用,但对于我需要的内容来说,它仍然太慢了。
我已经尝试过了精彩的h2o.importFolder
软件包中的h2o
,但与使用普通R
data.table
相比,它实际上要慢得多。也许有办法加快文件的解压缩,但我不确定。从我运行过的几次开始,我注意到解压缩文件通常占用了大约2/3的函数时间。
答案 0 :(得分:11)
我真的很惊讶这实际上有用了。希望它适用于您的情况。我非常想知道速度与从R直接从磁盘读取压缩数据的速度相比(尽管非矢量化会受到惩罚)。
tblNames = fread('cat *dat.gz | gunzip | head -n 1')[, colnames(.SD)]
tbl = fread('cat *dat.gz | gunzip | grep -v "^Day"')
setnames(tbl, tblNames)
tbl
答案 1 :(得分:6)
R能够使用gzfile
函数本机读取gzip压缩文件。看看是否有效。
rbindlist(lapply(dat.files, function(f) {
read.delim(gzfile(f))
}))
答案 2 :(得分:4)
瓶颈可能是由于使用system()调用外部应用程序引起的。
您应该尝试使用构建函数来提取存档。 这个答案解释了如何:Decompress gz file using R