确定数据框中每个日期区间是否与所有其他日期区间重叠。

3
对于我的数据框中的每个日期区间行,我想确定它是否与所有其他日期区间重叠。除了自己之外, 数据框包含开始日期和结束日期,表示时间间隔:
`data <- read.table(header=TRUE,text="
start.date             end.date
2019-09-01             2019-09-10
2019-09-05             2019-09-07
2019-08-25             2019-09-05
2019-10-10             2019-10-15
")`

这个函数 lubridate::int_overlaps() 通过返回逻辑值 TRUE 或 FALSE 来检查两个日期区间是否重叠。

`int_overlaps(interval(ymd("2019-09-01"),ymd("2019-09-10")), interval(ymd("2019-09-05"), ymd("2019-09-07")))
[1] TRUE
int_overlaps(interval(ymd("2019-09-01"),ymd("2019-09-10")), interval(ymd("2019-10-10"), ymd("2019-10-15")))
[1] FALSE`

我希望使用int_overlap()迭代每个日期间隔,并将所有不包括它自己的日期间隔与其比较,以确定它是否与其他日期重叠。 输出应该像这样:
`data <- read.table(header=TRUE,text="
start.date             end.date         overlaps
2019-09-01             2019-09-10       TRUE
2019-09-05             2019-09-07       TRUE
2019-08-25             2019-09-05       TRUE
2019-10-10             2019-10-15       FALSE
")
`
2个回答

3

下面是使用dplyrpurrr的一种选项,我们通过循环Int的索引来比较当前间隔与其他间隔。

library(dplyr)
library(purrr)
library(lubridate)
data %>% mutate(Int = interval(start.date, end.date), 
                overlaps = map(seq_along(Int), function(x){
                  #browser()
                  #Get all Int indexes other than the current one
                  y = setdiff(seq_along(Int), x)
                  #The interval overlaps with all other intervals
                  #return(all(int_overlaps(Int[x], Int[y])))
                  #The interval overlaps with any other intervals
                  return(any(int_overlaps(Int[x], Int[y])))
                }))

  start.date   end.date                            Int overlaps
1 2019-09-01 2019-09-10 2019-09-01 UTC--2019-09-10 UTC     TRUE
2 2019-09-05 2019-09-07 2019-09-05 UTC--2019-09-07 UTC     TRUE
3 2019-08-25 2019-09-05 2019-08-25 UTC--2019-09-05 UTC     TRUE
4 2019-10-10 2019-10-15 2019-10-10 UTC--2019-10-15 UTC    FALSE

1
我很惊讶!这正是我使用any()map()seq_along()寻找的答案。非常感谢你,Abubaker :) - Mohamed Mostafa El-Sayyad

1
我认为可以通过 dplyr 和 ivs 包的组合完成得很好,该包用于处理区间向量,这就是你所拥有的。
library(ivs)
library(dplyr)

data <- tribble(
  ~start.date,    ~end.date,
  "2019-09-01", "2019-09-10",
  "2019-09-05", "2019-09-07",
  "2019-08-25", "2019-09-05",
  "2019-10-10", "2019-10-15"
)

# Parse the dates and then convert them into an interval vector
data <- data %>%
  mutate(
    start = as.Date(start.date),
    end = as.Date(end.date),
    .keep = "unused"
  ) %>%
  mutate(interval = iv(start, end), .keep = "unused")

# Note that interval vectors are half-open! You may need to adjust your end
# dates by 1 depending on how you interpret them.
data
#> # A tibble: 4 × 1
#>                   interval
#>                 <iv<date>>
#> 1 [2019-09-01, 2019-09-10)
#> 2 [2019-09-05, 2019-09-07)
#> 3 [2019-08-25, 2019-09-05)
#> 4 [2019-10-10, 2019-10-15)

# Use `iv_identify_group()` to identify the wider "overlap group" that rows 1-3
# fall in, noting that row 4 gets its own group. Then it is just a matter of
# grouping by `groups` and checking if there is more than one value in each group
data %>%
  mutate(groups = iv_identify_group(interval)) %>%
  group_by(groups) %>%
  mutate(overlaps = n() > 1)
#> # A tibble: 4 × 3
#> # Groups:   groups [2]
#>                   interval                   groups overlaps
#>                 <iv<date>>               <iv<date>> <lgl>   
#> 1 [2019-09-01, 2019-09-10) [2019-08-25, 2019-09-10) TRUE    
#> 2 [2019-09-05, 2019-09-07) [2019-08-25, 2019-09-10) TRUE    
#> 3 [2019-08-25, 2019-09-05) [2019-08-25, 2019-09-10) TRUE    
#> 4 [2019-10-10, 2019-10-15) [2019-10-10, 2019-10-15) FALSE

这段文字是由reprex包(v2.0.1)于2022年4月5日创建的


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接