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
最近我不得不根据时间戳连接两个数据帧。 左侧数据包含固定时间戳,右侧数据包含范围。 正如您在我的 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