首页 > 解决方案 > 具体匹配两个数据框中的两个日期

问题描述

我想在特定日期之间获得计数(行)的 sum()。我在堆栈上找到了一些解决方案,但关键是我的第二个数据框比第一个数据框大得多。

数据集一

昏暗(foo1)#600 / 2

Start                      End
2017-10-24 22:33:59   2017-10-24 22:43:59
2017-11-13 06:34:59   2017-11-13 06:44:59
2017-11-13 06:52:00   2017-11-13 07:02:00
2017-11-13 07:16:59   2017-11-13 07:26:59
2017-11-13 07:35:59   2017-11-13 07:45:59

数据集二

昏暗(foo2)#60.000 / 2

Count           Time
1              2017-10-01 13:45:02
1              2017-10-01 12:53:23
1              2017-10-01 12:20:56
1              2017-10-01 12:31:12

我想要来自 foo2 的所有行(计数)的总和,出现在 foo1 的开始日期和结束日期之间)。结果应该是 Foo1 + new_column (包含计数)

这是我开始不起作用的“解决方案”:

for(i in 1:nrow(foo1)){
  foo1$new_column[i] <-sum(foo2$Count[which( 
    foo2$Time >= foo2$Start[i] &
      foo2$Time <= foo2$End[i])]) 
}

标签: rjointime

解决方案


您的样本数据似乎存在问题,因为 no Timefrom foo2(all on 2017-10-01) 不在foo1(ranges start at 2017-10-24) 的时间间隔内。

对于这个答案,我创建了自己的示例数据。

library(data.table)

foo1 <- data.table( Start = c("2017-10-24 22:33:59", "2017-11-13 06:34:59", "2017-11-13 06:52:00", "2017-11-13 07:16:59", "2017-11-13 07:35:59"),
                    End = c("2017-10-24 22:43:59", "2017-11-13 06:44:59", "2017-11-13 07:02:00", "2017-11-13 07:26:59", "2017-11-13 07:45:59"),
                    stringsAsFactors = FALSE)

#                  Start                 End
# 1: 2017-10-24 22:33:59 2017-10-24 22:43:59
# 2: 2017-11-13 06:34:59 2017-11-13 06:44:59
# 3: 2017-11-13 06:52:00 2017-11-13 07:02:00
# 4: 2017-11-13 07:16:59 2017-11-13 07:26:59
# 5: 2017-11-13 07:35:59 2017-11-13 07:45:59

foo2 <- data.table( Count = c(1,1,1,1),
                    Time = c("2017-10-24 22:37:02", "2017-10-24 22:38:23", "2017-11-13 07:20:56", "2017-10-01 12:31:12"),
                    stringsAsFactors = FALSE)

#    Count                Time
# 1:     1 2017-10-24 22:37:02
# 2:     1 2017-10-24 22:38:23
# 3:     1 2017-11-13 07:20:56
# 4:     1 2017-10-01 12:31:12

#set times as POSIXct
foo1[, Start := as.POSIXct(Start, format = "%Y-%m-%d %H:%M:%S")]
foo1[, End := as.POSIXct(End, format = "%Y-%m-%d %H:%M:%S")]
foo2[, Time :=  as.POSIXct(Time, format = "%Y-%m-%d %H:%M:%S")]

#add a dummy-column to create a time-range (of 1 second)
foo2[, dummy := Time]

#set data.table keys
setkey(foo1, Start, End)
setkey(foo2, Time, dummy)

#overlap-join, lose the dummy-column
foo3 <- foverlaps(foo2, foo1, type = "within", mult = "first", nomatch = 0L)[, dummy := NULL]

#                  Start                 End Count                Time
# 1: 2017-10-24 22:33:59 2017-10-24 22:43:59     1 2017-10-24 22:37:02
# 2: 2017-10-24 22:33:59 2017-10-24 22:43:59     1 2017-10-24 22:38:23
# 3: 2017-11-13 07:16:59 2017-11-13 07:26:59     1 2017-11-13 07:20:56

foo3[, sum(Count), by = "Start"]
#                  Start V1
# 1: 2017-10-24 22:33:59  2
# 2: 2017-11-13 07:16:59  1

推荐阅读