【问题标题】:Find interval overlap within time arbitrary bins with lubridate使用 lubridate 查找时间任意区间内的间隔重叠
【发布时间】:2017-07-18 21:23:35
【问题描述】:

我有一个数据集,它有一个任意 5 分钟的间隔时间,在 Period 列中表示。不同观察的周期(IDs)从不同的时间开始(对于 ID='83',它从 49M 开始,而对于 ID='90',它从 50M 开始)。观察结果是存储在Start.N 和End.N 列中的时间间隔。

最后 2 列有一个间隔,表示观察的连续时间或“事件”(无论周期如何),因此它是重复的。一些观察有多个“事件”,并且重复周期以适应这些额外的间隔

我的目标是计算事件和任意 bin 之间重叠的分钟和秒数。澄清一下,第一行应该有重叠0M 0S,而第二行应该有5M 0S重叠,因为54M 0S - 59M 0S包含在54M 1S - 89M 0S中。

  ID Period Period.start Period.end Start.N  End.N
1 83      5       49M 0S     54M 0S  54M 1S 89M 0S
2 83     10       54M 0S     59M 0S  54M 1S 89M 0S
3 83     15       59M 0S     64M 0S  54M 1S 89M 0S
4 83     20       64M 0S     69M 0S  54M 1S 89M 0S
5 83     25       69M 0S     74M 0S  54M 1S 89M 0S
6 83     30       74M 0S     79M 0S  54M 1S 89M 0S

这是我的数据

structure(list(ID = c("83", "83", "83", "83", "83", "83", "83", 
"83", "83", "83", "90", "90", "90", "90", "90", "90", "90", "90", 
"90", "90", "90", "90", "90", "90", "90", "90", "90", "90", "90", 
"90"), Period = c(5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 5, 5, 
10, 10, 15, 15, 20, 20, 25, 25, 30, 30, 35, 35, 40, 40, 45, 45, 
50, 50), Period.start = structure(c(0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
), year = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), month = c(0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0), day = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), hour = c(0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0), minute = c(49, 54, 59, 64, 69, 74, 79, 
84, 89, 94, 50, 50, 55, 55, 60, 60, 65, 65, 70, 70, 75, 75, 80, 
80, 85, 85, 90, 90, 95, 95), class = structure("Period", package = "lubridate")), 
    Period.end = structure(c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), year = c(0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0), month = c(0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0), day = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), hour = c(0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0), minute = c(54, 59, 64, 69, 
    74, 79, 84, 89, 94, 99, 55, 55, 60, 60, 65, 65, 70, 70, 75, 
    75, 80, 80, 85, 85, 90, 90, 95, 95, 100, 100), class = structure("Period", package = "lubridate")), 
    Start.N = structure(c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 32, 32, 
    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
    32, 32, 32), year = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L), month = c(0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), day = c(0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), hour = c(0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), minute = c(54, 
    54, 54, 54, 54, 54, 54, 54, 54, 54, 52, 94, 52, 94, 52, 94, 
    52, 94, 52, 94, 52, 94, 52, 94, 52, 94, 52, 94, 52, 94), class = structure("Period", package = "lubridate")), 
    End.N = structure(c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), year = c(0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), month = c(0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), day = c(0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), hour = c(0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), minute = c(89, 
    89, 89, 89, 89, 89, 89, 89, 89, 89, 83, 111, 83, 111, 83, 
    111, 83, 111, 83, 111, 83, 111, 83, 111, 83, 111, 83, 111, 
    83, 111), class = structure("Period", package = "lubridate"))), .Names = c("ID", 
"Period", "Period.start", "Period.end", "Start.N", "End.N"), row.names = c(NA, 
30L), class = "data.frame")

【问题讨论】:

  • 你的困难是什么?比较开始/结束似乎很简单,如果有重叠,则计算相应的结束开始。
  • @eddi 我不知道如何计算特定箱内每个 Start.N - End.N 间隔的重叠。我对ifelse(Period.start>=Start.N & Period.end < End.N , 'contained', 'not contained') 之类的东西有一个想法,但是在几秒钟内计算实际重叠我不知道。此外,我需要为每个独特的 Start.N 和 End.N 事件实现此功能,将其集成到某些 dplyr 链中的 mutate 中
  • @MatiasAndina 像这样:ifelse(Period.start > End.N | Period.end < Start.N, 0, pmin(End.N - Period.start, Period.end - Start.N));如果您的问题是弄清楚如何从彼此中减去任何类别的对象并以任何格式呈现 - 环顾四周或发布有关该问题的问题
  • @eddi 我喜欢你的 ifelse 语句,它没有做我需要的操作,但它非常接近。由于它很方便地按行执行,当事件大于 5 分钟时,下一个周期的减法类似于 5M 30S; 10M 30S; 15M 30S, ...我想我的问题确实是关于操作的,但我不认为这很简单,也不理解反对票。您可以发布您的代码作为答案,我会添加它。

标签: r overlap lubridate


【解决方案1】:

这是我用来解决问题的方法。 ifelse 由 eddi 提供,我后来做了 dplyr 数据管理,我很高兴收到更高效的程序员的意见。

    new.data %>% mutate(NPeriodStart = End.N - Period.start,
        PeriodEndStartN = Period.end - Start.N,
         N.Time.Prep=ifelse(Period.start > End.N | Period.end < Start.N,
                             0,
lubridate::seconds(pmin(End.N - Period.start, Period.end - Start.N)))) %>%

  ###  We fix the over 300 seconds so that it's max 300 (5 min bin)

  mutate(N.Time = ifelse(N.Time.Prep>300, 300, N.Time.Prep)) %>%
  select(-NPeriodStart, - PeriodEndStartN, - N.Time.Prep)


  ## Finally, we get a data frame with just what we want

  # ID, Period, N time  
  # To get rid of the repeated measures (more than one N bout)
  # we summarize and select the max value  

  new.data <- new.data %>%
                group_by(ID, Period) %>% 
                summarise(N.Time = max(N.Time))  

【讨论】:

    猜你喜欢
    • 2020-02-19
    • 1970-01-01
    • 1970-01-01
    • 2018-03-22
    • 1970-01-01
    • 1970-01-01
    • 2020-02-24
    • 1970-01-01
    • 2023-01-10
    相关资源
    最近更新 更多