Home > Blockchain >  Calculate time intervals without any overlap
Calculate time intervals without any overlap

Time:09-16

I have the following data:

# dput:
data <- structure(list(start = structure(c(1641193200, 1641189600, 1641218400, 
1641189600, 1641222000, 1641222000, 1641222000), class = c("POSIXct", 
"POSIXt"), tzone = "UTC"), end = structure(c(1641218400, 1641218400, 
1641241800, 1641218400, 1641241800, 1641241800, 1641232800), class = c("POSIXct", 
"POSIXt"), tzone = "UTC"), group = c("A", "B", "C", "D", "E", 
"F", "G")), row.names = c(NA, -7L), class = c("tbl_df", "tbl", 
"data.frame"))

data

# A tibble: 7 x 3
  start               end                 group
  <dttm>              <dttm>              <chr>
1 2022-01-03 07:00:00 2022-01-03 14:00:00 A    
2 2022-01-03 06:00:00 2022-01-03 14:00:00 B    
3 2022-01-03 14:00:00 2022-01-03 20:30:00 C    
4 2022-01-03 06:00:00 2022-01-03 14:00:00 D    
5 2022-01-03 15:00:00 2022-01-03 20:30:00 E    
6 2022-01-03 15:00:00 2022-01-03 20:30:00 F    
7 2022-01-03 15:00:00 2022-01-03 18:00:00 G 


And I want to calculate at what time there only 1 group has an "active" time interval (start to end) without overlapping with any other group. I already experimented with lubridate and the interval function but had trouble comparing more than 2 Intervals with each other.

Desired Output

The output should give the result that the group C has the time interval from 14:00 to 15:00 that has no overlap with any other group.

CodePudding user response:

You can check ivs::iv_locate_splits to see which time frame is occupied by which group:

library(ivs)
ivv <- iv(data$start, data$end)
iv_locate_splits(ivv)

                                         key        loc
1 [2022-01-03 06:00:00, 2022-01-03 07:00:00)       2, 4
2 [2022-01-03 07:00:00, 2022-01-03 08:00:00)    1, 2, 4
3 [2022-01-03 08:00:00, 2022-01-03 14:00:00) 1, 2, 4, 7
4 [2022-01-03 14:00:00, 2022-01-03 15:00:00)       3, 7
5 [2022-01-03 15:00:00, 2022-01-03 18:00:00) 3, 5, 6, 7
6 [2022-01-03 18:00:00, 2022-01-03 20:30:00)    3, 5, 6

Updated framework to get the desired outcome:

library(ivs)

#convert to iv format
ivv <- iv(data$start, data$end)

#Check the splits
spl <- iv_locate_splits(ivv)

#Get the index of splits with only 1 group 
index <- unlist(spl$loc[lengths(spl$loc) == 1])

#Create the desired outcome using the index
data.frame(frame = spl$key[index],
           group = data$group[index])

#                                       frame group
#1 [2022-01-03 14:00:00, 2022-01-03 15:00:00)     C
  • Related