R: 如何阻止 fuzzyjoin::interval_join 在边缘产生重复?

R: How to stop fuzzyjoin::interval_join from producing duplicates on the edges?

最近我不得不根据时间戳连接两个数据帧。 左侧数据包含固定时间戳,右侧数据包含范围。 正如您在我的 MWE 中看到的那样,我大部分时间都在使用它,但系统往往会在从一个范围到下一个范围的交叉点处产生重复的结果。我已经尝试了所有选项,但没有任何效果。

有什么好的方法可以抑制重复条目吗?
在这个例子中,它是粗体,数字 13。 当然你也可以试试过滤,不过感觉比较hacky

left.data <- data.frame(
  Data.left = 1:20,
  Timestamp = seq(
    ISOdatetime(2000, 1, 1, 10, 55, 10),
    by = "5 min",
    length.out = 20
  )
)

right.data <- data.frame(
  Data.right = 1:10,
  PeriodStartTime = seq(
    ISOdatetime(2000, 1, 1, 10, 55, 10),
    by = "hour",
    length.out = 10
  ),
  PeriodEndTime = seq(
    ISOdatetime(2000, 1, 1, 11, 55, 10),
    by = "hour",
    length.out = 10
  )
)

result <- fuzzyjoin::interval_join(
    x = left.data,
    y = right.data,
    by = c(
      "Timestamp" = "PeriodStartTime",
      "Timestamp" = "PeriodEndTime"
    ),
    mode = "left"
  )
Data.left Timestamp Data.right PeriodStartTime PeriodEndTime
1 2000-01-01 10:55:10 1 2000-01-01 10:55:10 2000-01-01 11:55:10
2 2000-01-01 11:00:10 1 2000-01-01 10:55:10 2000-01-01 11:55:10
3 2000-01-01 11:05:10 1 2000-01-01 10:55:10 2000-01-01 11:55:10
4 2000-01-01 11:10:10 1 2000-01-01 10:55:10 2000-01-01 11:55:10
5 2000-01-01 11:15:10 1 2000-01-01 10:55:10 2000-01-01 11:55:10
6 2000-01-01 11:20:10 1 2000-01-01 10:55:10 2000-01-01 11:55:10
7 2000-01-01 11:25:10 1 2000-01-01 10:55:10 2000-01-01 11:55:10
8 2000-01-01 11:30:10 1 2000-01-01 10:55:10 2000-01-01 11:55:10
9 2000-01-01 11:35:10 1 2000-01-01 10:55:10 2000-01-01 11:55:10
10 2000-01-01 11:40:10 1 2000-01-01 10:55:10 2000-01-01 11:55:10
11 2000-01-01 11:45:10 1 2000-01-01 10:55:10 2000-01-01 11:55:10
12 2000-01-01 11:50:10 1 2000-01-01 10:55:10 2000-01-01 11:55:10
13 2000-01-01 11:55:10 1 2000-01-01 10:55:10 2000-01-01 11:55:10
13 2000-01-01 11:55:10 2 2000-01-01 11:55:10 2000-01-01 12:55:10
14 2000-01-01 12:00:10 2 2000-01-01 11:55:10 2000-01-01 12:55:10
15 2000-01-01 12:05:10 2 2000-01-01 11:55:10 2000-01-01 12:55:10
16 2000-01-01 12:10:10 2 2000-01-01 11:55:10 2000-01-01 12:55:10
17 2000-01-01 12:15:10 2 2000-01-01 11:55:10 2000-01-01 12:55:10
18 2000-01-01 12:20:10 2 2000-01-01 11:55:10 2000-01-01 12:55:10
19 2000-01-01 12:25:10 2 2000-01-01 11:55:10 2000-01-01 12:55:10
20 2000-01-01 12:30:10 2 2000-01-01 11:55:10 2000-01-01 12:55:10

也许有人会用 interval_join 提供另一个答案,但这里需要考虑 fuzzy_left_join

您的匹配函数 match_fun 可以设置为允许范围的下限相等(大于或等于),但小于上限。

library(fuzzyjoin)

fuzzy_left_join(
  left.data,
  right.data,
  by = c(
    "Timestamp" = "PeriodStartTime",
    "Timestamp" = "PeriodEndTime"
  ),
  match_fun = c(`>=`, `<`)
)

这个结果会给你:

   Data.left           Timestamp Data.right     PeriodStartTime       PeriodEndTime
1          1 2000-01-01 10:55:10          1 2000-01-01 10:55:10 2000-01-01 11:55:10
2          2 2000-01-01 11:00:10          1 2000-01-01 10:55:10 2000-01-01 11:55:10
3          3 2000-01-01 11:05:10          1 2000-01-01 10:55:10 2000-01-01 11:55:10
4          4 2000-01-01 11:10:10          1 2000-01-01 10:55:10 2000-01-01 11:55:10
5          5 2000-01-01 11:15:10          1 2000-01-01 10:55:10 2000-01-01 11:55:10
6          6 2000-01-01 11:20:10          1 2000-01-01 10:55:10 2000-01-01 11:55:10
7          7 2000-01-01 11:25:10          1 2000-01-01 10:55:10 2000-01-01 11:55:10
8          8 2000-01-01 11:30:10          1 2000-01-01 10:55:10 2000-01-01 11:55:10
9          9 2000-01-01 11:35:10          1 2000-01-01 10:55:10 2000-01-01 11:55:10
10        10 2000-01-01 11:40:10          1 2000-01-01 10:55:10 2000-01-01 11:55:10
11        11 2000-01-01 11:45:10          1 2000-01-01 10:55:10 2000-01-01 11:55:10
12        12 2000-01-01 11:50:10          1 2000-01-01 10:55:10 2000-01-01 11:55:10
13        13 2000-01-01 11:55:10          2 2000-01-01 11:55:10 2000-01-01 12:55:10
14        14 2000-01-01 12:00:10          2 2000-01-01 11:55:10 2000-01-01 12:55:10
15        15 2000-01-01 12:05:10          2 2000-01-01 11:55:10 2000-01-01 12:55:10
16        16 2000-01-01 12:10:10          2 2000-01-01 11:55:10 2000-01-01 12:55:10
17        17 2000-01-01 12:15:10          2 2000-01-01 11:55:10 2000-01-01 12:55:10
18        18 2000-01-01 12:20:10          2 2000-01-01 11:55:10 2000-01-01 12:55:10
19        19 2000-01-01 12:25:10          2 2000-01-01 11:55:10 2000-01-01 12:55:10
20        20 2000-01-01 12:30:10          2 2000-01-01 11:55:10 2000-01-01 12:55:10