我正试图根据日期/时间范围(开始和结束时间(和另一个数据集中每一行的id来筛选数据集。最终结果应该是经过筛选的数据帧的列表。
下面是创建这两个数据集的代码。
#This is the dataset to filter
x <- as.data.frame(format(seq.POSIXt(as.POSIXct("2019-01-01 07:00"), as.POSIXct("2019-01-01 11:50"), by = "10 min"))) #date/time
y <- as.data.frame(format(seq.POSIXt(as.POSIXct("2019-01-01 07:00"), as.POSIXct("2019-01-01 11:50"), by = "10 min"))) #date/time
datetime <- rbind(list(x,y))
datetime <- do.call(rbind, datetime)
datetime <- rename(datetime, datetime=`format(seq.POSIXt(as.POSIXct("2019-01-01 07:00"), as.POSIXct("2019-01-01 11:50"), by = "10 min"))`)
datetime
values <- c(1:60) #value
id <- vector(mode="character", length=60)
#id <- rep(letters[1:5], 6) #id
dataloggers <- data.frame(datetime, values, id)
head(dataloggers)
dataloggers[c(1:10), 3] ="a"
dataloggers[c(11:30), 3]="b"
dataloggers[c(31:60), 3]="c"
dataloggers$datetime <- ymd_hms(dataloggers$datetime)
#and this is the dataset used to filter the dataset above
starttime <- as.POSIXct(c("2019-01-01 07:00", "2019-01-01 08:40", "2019-01-01 07:00:00"))
starttime <- ymd_hms(starttime)
datetime <- as.POSIXct(c("2019-01-01 08:00", "2019-01-01 10:00", "2019-01-01 08:00"))
datetime <- ymd_hms(datetime)
id <- rep(letters[1:3])
data<- data.frame(starttime,datetime, id)
我已经设法使用for()
循环来过滤日期/时间范围:
my_list <- list() #create empty list
for(i in seq_along(data$starttime)) {
output <- dataloggers %>%
filter(between(dataloggers$datetime, data$starttime[i], data$datetime[i]))
my_list[[i]] <- output
}
my_list <- do.call(rbind, my_list)
my_list
但正如您所看到的,它只根据开始和结束时间过滤数据帧。我还需要它根据匹配的id进行过滤。left_join()
没有给我想要的,因为我不想合并数据集。我只想有一个基于这两个条件的过滤数据帧列表。如有任何帮助,我们将不胜感激。
这里有两种方法:
- 基于范围的模糊联接:
fuzzyjoin::fuzzy_inner_join(dataloggers, data,
by = c('id', 'datetime' = 'starttime', 'datetime'),
match_fun = list(`==`, `>=`, `<=`))
通过
id
加入并将数据保持在范围内a。
dplyr
:
library(dplyr)
dataloggers %>%
inner_join(data, by = 'id') %>%
filter(datetime.x >= starttime & datetime.x <= datetime.y)
b。基本R:
subset(merge(dataloggers, data, by = 'id'),
datetime.x >= starttime & datetime.x <= datetime.y)