类似于此处未回答的问题: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
答案 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