在 R 中,如何在同一 group_by 中找到属于由行定义的日期范围的其他行?

In R, how to find other rows in the same group_by that belong to a date range defined by row?

在 R 中我有这个对象:

z <- 
  dplyr::tribble(
    ~event_id, ~group_id, ~date_event, ~date_min,   ~date_max,  
    1, 1, "2019-11-11", "2019-11-04", "2019-11-18",
    2, 1, "2019-11-13", "2019-11-06", "2019-11-20",
    3, 1, "2019-11-19", "2019-11-12", "2019-11-26",
    4, 1, "2020-04-30", "2020-04-23", "2020-05-07",
    5, 2, "2019-11-05",  "2019-10-29", "2019-11-12",
    6, 2, "2019-11-26", "2019-11-19", "2019-12-03"
    ) %>%
  dplyr::mutate_if(is.character,lubridate::as_date)

我的数据遵循这种结构:每行一个 event_id; group_id 每组; date_event;以及 date_event 之前 7 天和之后 7 天之间的范围(date_min 和 date_max)。

我想知道的是:对于每一行(每个事件),同一 group_id 内匹配范围的其他事件是什么(基于 date_min 和 date_max) 对于那一行?!

一个输出示例:

我不确定我到底想要什么输出格式,但我需要这个结果,但我不知道如何解决它。

有人可以帮忙吗? 提前致谢。最好的,弗拉基米尔。

您可以先分组,然后使用 purrr::map2。为此,您传入那些日期阈值以同时进行映射,并将事件 ID 和日期向量作为附加参数传递:

library(dplyr)
library(purrr)

z2 <- z %>%
  group_by(group_id) %>%
  mutate(
    event_ids_in_window = map2(
      date_min, date_max,
      event_ids = event_id, dates = date_event,
      .f = function(date_min, date_max, event_ids, dates) {
        event_ids[which(dates >= date_min & dates <= date_max)]
      }
    )
  )

您可以使用正则表达式联接将数据与其自身联接并计算范围内的日期。

data <- fuzzyjoin::fuzzy_inner_join(z, z, 
       by = c('group_id', 'date_min' = 'date_event', 'date_max' = 'date_event'), 
       match_fun = c(`==`, `<=`, `>=`))

现在计算您可以使用的每个 ID 有多少个 ID 重叠:

library(dplyr)
data %>% count(event_id.x, group_id.x)

# A tibble: 6 x 3
#  event_id.x group_id.x     n
#       <dbl>      <dbl> <int>
#1          1          1     2
#2          2          1     3
#3          3          1     2
#4          4          1     1
#5          5          2     1
#6          6          2     1

要获取重叠的 ID,您可以使用:

data %>%
  group_by(event_id.x) %>%
  summarise(other_ids = list(event_id.y))

#  event_id.x other_ids
#       <dbl> <list>   
#1          1 <dbl [2]>
#2          2 <dbl [3]>
#3          3 <dbl [2]>
#4          4 <dbl [1]>
#5          5 <dbl [1]>
#6          6 <dbl [1]>

请注意,每个 ID 也与自身重叠,因此如果您需要通过执行 filter(event_id.x != event_id.y).

从数据中删除此类 ID

我们可以使用 non-equi 加入 data.table

library(data.table)
setDT(z)[z, .N, on = .(group_id, date_min <= date_event,
         date_max >= date_event), by = .EACHI]
#    group_id   date_min   date_max N
#1:        1 2019-11-11 2019-11-11 2
#2:        1 2019-11-13 2019-11-13 3
#3:        1 2019-11-19 2019-11-19 2
#4:        1 2020-04-30 2020-04-30 1
#5:        2 2019-11-05 2019-11-05 1
#6:        2 2019-11-26 2019-11-26 1

和 return 'dates' 和行索引

setDT(z)[z, .(.N, dates = .(date_event), rn = .(.I)), on = 
    .(group_id, date_min <= date_event,
        date_max >= date_event), by = .EACHI]