r - 日期时间 - 确定多个(n)日期时间范围是否在 R 中相互重叠

标签 r algorithm datetime math

嗨, friend 们,我无法确定多个日期时间范围是否相互重叠,如果是,它们重叠的时间段。我已经引用了以下链接 Determine Whether Two Date Ranges OverlapAlgorithm to detect overlapping periods还有一些。

不知道这对不对,我有 n=3 的示例解释。

假设我有“n”个开关 sw1、sw2 和 sw3。状态是开/关状态,即 1/0。

Switches,State,Intime,Outtime

sw3,1,9:00:00,10:40:00
sw2,1,9:30:00,10:15:00
sw1,1,10:00:00,11:00:00
sw2,1,10:20:00,10:30:00

我遇到过这种可能性。可能还有更多。仍在寻找其他可能性。这里的常见时间段是从 10:00 到 10:15,即 15 分钟和 10:20 到 10:30,即 10 分钟。这些开关打开 ('1') 的组合时间段为 25 分钟。

                 10:00                           11:00
              sw1 |-----------------------------------|
       9:30       10:15   10:20     10:30
     sw2 |-------------|      |-------|
 9:00                                     10:40 
sw3 |----------------------------------------| 

为 n 个重叠开关概括此日期时间是一项艰巨的任务。我仍在努力,欢迎任何建议或修改。谢谢。

最佳答案

1) 根据示例数据,我们假设数据的格式为 hh:mm:00,其中 hh < 24。

读入测试数据。创建两个将 hh:mm:00 形式的字符串转换为分钟数的函数和一个将分钟数转换为 chron "times" 对象的函数。为提供 Intervals 列表的每一行数据创建逐分钟序列。将对应于同一开关的那些序列联合起来,给出列表 Intervals.u,然后与该列表的组件相交,给出序列 Intersection。计算 Intersection 中的行程 r 以给出一组起点和终点。最后计算分钟数并将其转换为 "times" 类持续时间。 (分钟数和持续时间仅取决于 rIntersection,因此如果 intervals.df 不是,我们可以跳过以 ## 结尾的行需要。)

# test data
Lines <- "Switches,State,Intime,Outtime
sw3,1,9:00:00,10:40:00
sw2,1,9:30:00,10:15:00
sw1,1,10:00:00,11:00:00
sw2,1,10:20:00,10:30:00"
DF <- read.csv(text = Lines, as.is = TRUE)

library(chron)

to.num <- function(x) floor(as.numeric(times(x)) * 24 * 60 + 1e-6)
to.times <- function(x) times(x / (24 * 60))

Seq <- function(r) seq(to.num(DF$Intime[r]), to.num(DF$Outtime[r]))    
Intervals <- lapply(1:nrow(DF), Seq)
Intervals.u <- lapply(split(Intervals, DF$Switches), 
     function(L) Reduce(union, L))
Intersection <- Reduce(intersect, Intervals.u)

r <- rle(c(FALSE, diff(Intersection) == 1))

i.ends <- cumsum(r$lengths)[r$values] ##
ends <- to.times(Intersection[i.ends]) ##
starts <- ends - to.times(r$lengths[r$values]) ##
intervals.df <- data.frame(start = starts, end = ends); intervals.df ##
##         start      end
##    1 10:00:00 10:15:00
##    2 10:20:00 10:30:00

mins <- length(Intersection) - sum(r$values); mins
## [1] 25
duration <- to.times(mins); duration
## [1] 00:25:00

2) 关于与速度相关的注释,我们可以改用 IRanges 包,它可以有效地编码范围并稍微减少代码大小:

library(IRanges)
Intervals <- IRanges(to.num(DF$Intime), to.num(DF$Outtime))
Intersection <- Reduce(intersect, split(Intervals, DF$Switches))

intervals.df <- data.frame(start = to.times(start(Intersection)), 
                           end = to.times(end(Intersection)))
intervals.df
##      start      end
## 1 10:00:00 10:15:00
## 2 10:20:00 10:30:00

mins <- sum(width(Intersection) - 1); mins
## [1] 25
duration <- to.times(mins); duration
## [1] 00:25:00

更新 一些修复和更好的变量名称。进一步改进。添加了 (2)。

关于r - 日期时间 - 确定多个(n)日期时间范围是否在 R 中相互重叠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24736000/

相关文章:

r - 如何删除 tm 包内带有单词的括号?

r - R 编程中 datenum 的等价物

返回与连接的二维栅格中的点直接相邻的 8 个点

匹配时间相关 (1D) 信号的算法

datetime - Julia 将 Dates 包中的秒数转换为整数:没有方法匹配 Int64(::Second)

matlab - 时区应该如何格式化在Matlab中,当将字符串插入带有时区的postgresql字段时间戳时?

json - R data.frame 到带有子节点/分层结构的 JSON

algorithm - 哪种算法可以有效地找到路径一定距离内的一组点?

python - 用 python 解析 Facebook feed 日期时间?

r - 帮助加速 R 中的循环