我需要合并两个数据框。我要合并的字段是IP地址和时间(%H:%M)。我正在寻找IP地址字段中的完全匹配,但在时间字段中我希望在5分钟内(+/-)进行模糊匹配。例如,如果我有以下2个数据帧:
> df1
users1 IPs1 times1
1 user1 192.168.1.1 11:05
2 user2 192.168.1.2 20:31
3 user3 192.168.1.3 01:19
> df2
users2 IPs2 times2
1 userx 192.168.1.2 20:33
2 usery 192.168.1.3 01:19
3 userz 192.168.1.1 11:01
我想合并数据框以显示user1与userz相关,user2与userx相关,而user3与usery相关。我怎么能这样做?使用合并功能,我只会根据精确的时间匹配得到user3与usery的关联。
答案 0 :(得分:3)
您可以使用fuzzyjoin
包进行模糊合并。其中一个fuzzyjoin
函数是difference_join
,它允许您根据两个表中列之间的绝对差异进行连接。唯一的问题是,times1
和times2
是因子或字符向量,而不是数字。因此,我使用hms
将它们转换为数字列,然后以5分钟(5 * 60秒)的差异模糊地连接,并在IP彼此相同时进行过滤。
library(tidyverse)
library(fuzzyjoin)
library(hms)
hms <- Vectorize(hms)
df1 <- df1 %>%
separate(times1, c("hours", "minutes")) %>%
mutate_at(c("hours", "minutes"), as.integer) %>%
mutate(times = hms(0, minutes, hours))
df2 <- df2 %>%
separate(times2, c("hours", "minutes")) %>%
mutate_at(c("hours", "minutes"), as.integer) %>%
mutate(times = hms(0, minutes, hours))
difference_full_join(df1, df2, by = "times", max_dist = 5*60) %>%
filter(IPs1 == IPs2)
#> users1 IPs1 hours.x minutes.x times.x users2 IPs2 hours.y
#> 1 user1 192.168.1.1 11 5 39900 userz 192.168.1.1 11
#> 2 user2 192.168.1.2 20 31 73860 userx 192.168.1.2 20
#> 3 user3 192.168.1.3 1 19 4740 usery 192.168.1.3 1
#> minutes.y times.y
#> 1 1 39660
#> 2 33 73980
#> 3 19 4740