在两个数据帧上合并条件

时间:2017-09-10 11:08:11

标签: r dataframe

类似于此处未回答的问题:Merge two dataframes with condition on timestamp 但我的问题更为笼统而非时间序列

我有两个数据帧要与两个数据帧的两列上的接近条件合并。在SQL中我会做类似

的事情

select * from (select * from A) T1 inner join (select * from B) T2 on T1.user = T2.user and T1.label - T2.label < 2

我正在寻找的是一种在R中执行上述操作的canincal方法,例如 -

merge(x,y,by='user', condition = x$label - y$label <=2 )

所以以下应该没有第3,7,11,12,13,15行......

set.seed(1212)
a <- data.frame(user=rep(paste("u",1:3,sep=''),4),label=sample.int(10,12,T))
b <- data.frame(user=rep(paste("u",1:3,sep=''),4),label=sample.int(10,12,T))

merge(a,b,by='user')

   user label.x label.y
1    u1       3       1
2    u1       3       3
3    u1       3      10
4    u1       3       5
5    u1       3       1
6    u1       3       3
7    u1       3      10
8    u1       3       5
9    u1       1       1
10   u1       1       3
11   u1       1      10
12   u1       1       5
13   u1       4       1
14   u1       4       3
15   u1       4      10
16   u1       4       5
17   u2       7       1
18   u2       7       7
19   u2       7       4
20   u2       7       2
21   u2       2       1
22   u2       2       7
23   u2       2       4
24   u2       2       2
25   u2       6       1
26   u2       6       7
27   u2       6       4
28   u2       6       2
29   u2       1       1
30   u2       1       7
31   u2       1       4
32   u2       1       2
33   u3       8       7
34   u3       8       1
35   u3       8       7
36   u3       8       4
37   u3       1       7
38   u3       1       1
39   u3       1       7
40   u3       1       4
41   u3      10       7
42   u3      10       1
43   u3      10       7
44   u3      10       4
45   u3       9       7
46   u3       9       1
47   u3       9       7
48   u3       9       4

1 个答案:

答案 0 :(得分:2)

使用基数R,我会尝试:

subset(merge(a, b, by = 'user'), label.x - label.y <= 2)

如果数据量很大,我们可以尝试data.table

中的非等连接
library(data.table)
setDT(a)
setDT(b)

a[, label.a := label - 2]
b[, label.b := label]
y <- a[b, on = .(user, label.a <= label.b), allow.cartesian=TRUE][, label.a := NULL]
> head(y)
   user label i.label
1:   u1     1       1
2:   u1     3       1
3:   u1     3       1
4:   u2     1       7
5:   u2     2       7
6:   u2     6       7

此处label中的y是来自label的{​​{1}},a是来自label.i的{​​{1}}。

或更明确地说,使用label表达式:

b