我在文件夹中有一堆csv文件,每个文件都有一个日期在文件名中。我试图根据用户定义的开始和结束日期提取数据。我有以下代码
#Method1
f <- list.files("C:/Fileloc")
d <- data.frame()
#start and end dates are user inputs from Shiny
startdate = as.POSIXct("2015-10-01")
enddate = as.POSIXct("2016-09-30")
for(i in 1: length(f)){
filedate <- as.POSIXct(substr(f[i],5,14)) #File name example: XYZ_2015-10-05_ABCD.csv
if(between(filedate,startdate, enddate)) {
d<-rbind(d, fread(paste("C:/Fileloc",f[[i]],sep = "/"), sep = ";", header = FALSE,
blank.lines.skip = TRUE))
}
}
这里需要多长时间才能读取所有文件(本例中为366个文件)
user system elapsed
79.56 29.05 108.60
在这个网站上快速搜索后,我找到了一个解决方案,它说所有文件组合成一个.RDS文件然后进行子集化的速度更快。我使用以下代码来做到这一点。
#Method2
saveRDS(d, file = "Alldata.RDS") #d is the same data frame from Method1
dat <- readRDS("Alldata.RDS")
colnames(dat) <- c("Col1", "Date","Col3","Col4")
library(dplyr)
dat<-filter(dat, between(as.POSIXct(dat$Date, format = "%m/%d/%Y"),
as.POSIXct("2015-10-01"), as.POSIXct("2016-09-30")))
这就是运行此步骤所需要的。
user system elapsed
58.81 0.36 59.24
问题是,无论第二种方法中的开始日期和结束日期如何,都需要相同的时间,而如果日期范围内只有几天,则第一种方法会更快。我认为它正在发生,因为它每次都在搜索整个数据。
我想知道是否有更有效的方式来读取/分配数据?请注意,由于我在保存到.rds
之前按顺序绑定文件,因此.rds
文件中的日期列应该已按日期排序。我们可以在过滤时以某种方式利用它吗?
答案 0 :(得分:0)
暂不对帖子发表评论,所以我在这里回答 - 更快的分组方式是使用data.table格式:
d[Date %in% start_date:end_date, .(Col1, Date, Col3, Col4),]
那时您已经使用method1保存了d
。我发现仅使用名称而不是双引号来引用列更容易。
对于method1本身,我发现使用apply
系列函数而不是for
循环会更快。使用一个函数来解析所有文件名,以获得符合条件的名称向量(开始日期,结束日期),然后使用lapply(file_names, read_function)
读取所有数据。