r - 检查间隔开始和结束时间是否重叠

标签 r dplyr

我有这个数据框按结束时间排序:

 df = data.frame(ID= c(1,1,1,1,1,1,1),   NumberInSequence= c(1,2,3,4,5,6,7), 
                 StartTime = as.POSIXct(c("2016-01-15 18:02:11 GMT","2016-01-15 18:10:33 GMT","2016-01-15 18:25:08 GMT",
                                               "2016-01-15 18:33:56 GMT","2016-01-15 18:21:03 GMT","2016-01-15 19:55:09 GMT","2016-01-15 19:57:03 GMT"))  ,
                        EndTime = as.POSIXct(c("2016-01-15 18:02:17 GMT","2016-01-15 18:10:39 GMT","2016-01-15 18:25:14 GMT",
                                               "2016-01-15 18:34:02 GMT","2016-01-15 19:53:17 GMT","2016-01-15 19:56:15 GMT","2016-01-15 19:58:17 GMT"))
                       )

每一行都是一个时间间隔,包含开始时间和结束时间

df

 ID NumberInSequence           StartTime             EndTime
1  1                1 2016-01-15 18:02:11 2016-01-15 18:02:17
2  1                2 2016-01-15 18:10:33 2016-01-15 18:10:39
3  1                3 2016-01-15 18:25:08 2016-01-15 18:25:14
4  1                4 2016-01-15 18:33:56 2016-01-15 18:34:02
5  1                5 2016-01-15 18:21:03 2016-01-15 19:53:17
6  1                6 2016-01-15 19:55:09 2016-01-15 19:56:15
7  1                7 2016-01-15 19:57:03 2016-01-15 19:58:17

然后我使用 dplyr 添加几个字段来计算下一个开始时间和等待时间(即 NextStartTime 和 EndTime 之间的差值)。这将创建“WaitTime”列,该列在大多数情况下都有效,除非存在重叠的整数。

   df %>% group_by(ID) %>% 
      mutate(
      NextStartTime = lead(StartTime)[ifelse(lead(NumberInSequence) == (NumberInSequence + 1), TRUE, NA)] ,
      WaitTime = difftime(NextStartTime,EndTime, units = 's')
      #max_s = max(StartTime) #,
     # cum_max_s = as.POSIXct(cummin(as.numeric(StartTime)),origin="1970-01-01")
      )


  ID NumberInSequence           StartTime             EndTime       NextStartTime  WaitTime
1  1                1 2016-01-15 18:02:11 2016-01-15 18:02:17 2016-01-15 18:10:33  496 secs
2  1                2 2016-01-15 18:10:33 2016-01-15 18:10:39 2016-01-15 18:25:08  869 secs
3  1                3 2016-01-15 18:25:08 2016-01-15 18:25:14 2016-01-15 18:33:56  522 secs
4  1                4 2016-01-15 18:33:56 2016-01-15 18:34:02 2016-01-15 18:21:03 -779 secs
5  1                5 2016-01-15 18:21:03 2016-01-15 19:53:17 2016-01-15 19:55:09  112 secs
6  1                6 2016-01-15 19:55:09 2016-01-15 19:56:15 2016-01-15 19:57:03   48 secs
7  1                7 2016-01-15 19:57:03 2016-01-15 19:58:17                <NA>   NA secs

现在我需要添加一个名为“FLAG”的列,其值可以是“OK”或“NOT OK”

“确定”表示该间隔也不完全或部分位于另一个间隔内。因此带有“OK”的间隔与其他间隔没有重叠。

“NOT OK”表示该间隔部分或完全位于另一个间隔内。因此,带有“NOT OK”的间隔与其他间隔有重叠。

我有下面的间隔以及 FLAG 列的结果应该是什么以及简短的描述

 StartTime             EndTime              FLAG
2016-01-15 18:02:11 2016-01-15 18:02:17     OK - this interval does not overlap with other intervals
2016-01-15 18:10:33 2016-01-15 18:10:39     OK - this interval does not overlap with other intervals
2016-01-15 18:25:08 2016-01-15 18:25:14     NOT OK - this inerval is within the  18:21:03 start time interval 
2016-01-15 18:33:56 2016-01-15 18:34:02     NOT OK - this inerval is within the  18:21:03 start time interval 
2016-01-15 18:21:03 2016-01-15 19:53:17     NOT OK  - this interval contains other intervals 
2016-01-15 19:55:09 2016-01-15 19:56:15     OK - this interval does not overlap with other intervals
2016-01-15 19:57:03 2016-01-15 19:58:17     OK - this interval does not overlap with other intervals

我正在考虑在 dplyr 中使用 cummin 或 cummax......也许......

cum_max_s = as.POSIXct(cummin(as.numeric(StartTime)),origin="1970-01-01")

最佳答案

这是我为您所做的尝试。我认为 data.table 包中的 foverlaps() 是这种情况下的 friend 。你可以在 SO 上找到一些例子。您需要检查它们以了解该功能。您需要创建一个虚拟 data.table,包括开始和结束时间。就你而言,你有它们。我用最少的信息创建了dummy。然后,您使用 setkey() 并利用 foverlaps()

# Create a dummy dt for hoverlaps.
dummy <- setDT(df2)[, 1:4, with = FALSE]

# Use foverlaps().
setkey(setDT(df2), StartTime, EndTime)
foo <- foverlaps(dummy, setDT(df2), by.x = c("StartTime", "EndTime"))

现在,是时候清理数据了。对于每个 NumberInSequence,如果有超过 1 个重叠间隔 (n > 1),则删除具有相同开始和结束时间的行 (StartTime == i.StartTime & EndTime == i.EndTime)。然后,删除每个 NumberInSequence 的重复行。如果只有一行表明与另一个间隔重叠,那就足够了,对吗?最后,如果 StartTime == i.StartTime & EndTime == i.EndTimeTRUE,则意味着没有其他间隔与该间隔重叠。所以,你说好的。否则,不行。如有必要,稍后删除多余的列。

foo[,.SD[!(StartTime == i.StartTime & EndTime == i.EndTime & .N > 1)],
        by = c("ID","NumberInSequence")][!duplicated(NumberInSequence)][,
            check := ifelse(StartTime == i.StartTime & EndTime == i.EndTime,
                            "OK", "NOT OK")] -> out     
print(out)

#   ID NumberInSequence           StartTime             EndTime       NextStartTime  WaitTime i.ID i.NumberInSequence
#1:  1                1 2016-01-15 18:02:11 2016-01-15 18:02:17 2016-01-15 18:10:33  496 secs    1                  1
#2:  1                2 2016-01-15 18:10:33 2016-01-15 18:10:39 2016-01-15 18:25:08  869 secs    1                  2
#3:  1                5 2016-01-15 18:21:03 2016-01-15 19:53:17 2016-01-15 19:55:09  112 secs    1                  3
#4:  1                3 2016-01-15 18:25:08 2016-01-15 18:25:14 2016-01-15 18:33:56  522 secs    1                  5
#5:  1                4 2016-01-15 18:33:56 2016-01-15 18:34:02 2016-01-15 18:21:03 -779 secs    1                  5
#6:  1                6 2016-01-15 19:55:09 2016-01-15 19:56:15 2016-01-15 19:57:03   48 secs    1                  6
#7:  1                7 2016-01-15 19:57:03 2016-01-15 19:58:17                <NA>   NA secs    1                  7

#           i.StartTime           i.EndTime  check
#1: 2016-01-15 18:02:11 2016-01-15 18:02:17     OK
#2: 2016-01-15 18:10:33 2016-01-15 18:10:39     OK
#3: 2016-01-15 18:25:08 2016-01-15 18:25:14 NOT OK
#4: 2016-01-15 18:21:03 2016-01-15 19:53:17 NOT OK
#5: 2016-01-15 18:21:03 2016-01-15 19:53:17 NOT OK
#6: 2016-01-15 19:55:09 2016-01-15 19:56:15     OK
#7: 2016-01-15 19:57:03 2016-01-15 19:58:17     OK

关于r - 检查间隔开始和结束时间是否重叠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39759069/

相关文章:

r - R 中的矩阵运算 : parallelization, 稀疏运算,GPU 计算

r - 按天和小时获取数据总和

R dplyr : how to remove smaller groups?

r - 变更rowSums排除一栏

r - 将 SharePoint 站点数据导入 R

重新格式化数值而不强制转换为字符

r - 如何使用自定义函数并将其与 r 中的 dplyr group_by 一起使用?

r - 通过根据数据框中的数字添加行和值来扩展数据框

r - dplyr 重命名不适用于正则表达式

r - 过早地停止正在运行的 mcparallel 作业