计算每个类别(机器)的日期范围重叠的次数

Count how many times date ranges overlap for each category (machine)

有人可以帮我解决这个问题吗? 我需要创建一个列 Numb_times_with_overlap 来计算每台机器同时工作的次数。为此,我需要比较每台机器的工作时间间隔并分析是否存在重叠。这个想法是获得类似于此

的table

R 中的代码:

datateste <- data.frame(id = 1:9,
                        machine_id = c("A","B","C","A","A","B","C","B","A"),
                        start_time = c("01/12/2021  00:00:00","01/12/2021  04:15:10","01/12/2021  00:15:00","01/12/2021  00:05:07","01/12/2021  00:35:00","01/12/2021  04:00:00","01/12/2021  04:07:00","01/12/2021  04:44:34","01/12/2021  00:15:00"),
                        end_time = c("01/12/2021  00:10:10","01/12/2021  04:45:03","01/12/2021  00:30:53","01/12/2021  00:30:02","01/12/2021  00:39:00","01/12/2021  04:12:45","01/12/2021  04:34:00","01/12/2021  05:06:34","01/12/2021  00:35:00"))

datateste

首先,我建议使用 lubridate,因为这涉及时间间隔,purrr,因为您实际上需要遍历各个时间间隔以与列表进行比较。

根据您想要的结果写两篇笔记。首先,lubridate 将区间视为包含它们的边界,即如果两个区间共享一个边界,它们就会重叠。这意味着,例如,5A 和 9A 重叠,因为一个开始于 00:35:00,另一个结束于 00:35:00。其次,虽然从您的问题描述中不清楚,但您似乎只想在同一台机器上进行比较。比如4A和3C同时运行不算

library(dplyr)
library(lubridate)
library(purrr)

datateste %>% 
  mutate(
    run_interval = interval(dmy_hms(start_time), dmy_hms(end_time)),
    numb_times_with_overlap = imap_int(
      run_interval, 
      ~sum(
        int_overlaps(.x, run_interval) & 
          (machine_id == machine_id[.y])
        ) - 1L
    )
  ) %>% 
  select(-run_interval)

#>   id machine_id          start_time            end_time numb_times_with_overlap
#> 1  1          A 01/12/2021 00:00:00 01/12/2021 00:10:10                       1
#> 2  2          B 01/12/2021 04:15:10 01/12/2021 04:45:03                       1
#> 3  3          C 01/12/2021 00:15:00 01/12/2021 00:30:53                       0
#> 4  4          A 01/12/2021 00:05:07 01/12/2021 00:30:02                       2
#> 5  5          A 01/12/2021 00:35:00 01/12/2021 00:39:00                       1
#> 6  6          B 01/12/2021 04:00:00 01/12/2021 04:12:45                       0
#> 7  7          C 01/12/2021 04:07:00 01/12/2021 04:34:00                       0
#> 8  8          B 01/12/2021 04:44:34 01/12/2021 05:06:34                       1
#> 9  9          A 01/12/2021 00:15:00 01/12/2021 00:35:00                       2

首先,我们创建一列间隔 (run_interval)。然后我们可以使用映射函数遍历此列,在本例中为 imap_int。这会将行与整列进行比较,以使用 int_overlap,然后仅包含 machine_id 匹配该行的行(.y 参数是当前行的索引)。求和一个逻辑向量给你一个计数,你需要减去 1 来解释自匹配。

由于前面提到的 lubridate 确定重叠的方式,计数与您的预期结果不同。如果您不想要这个间隔定义,我想解决方法是在每个开始时间添加一微秒。