【问题标题】:merge with condition on two dataframes与两个数据帧上的条件合并
【发布时间】:2018-02-18 18:30:22
【问题描述】:

类似于此处未回答的问题: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 中执行上述操作的典型方法,例如-

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

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    使用base R,我会尝试:

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

    如果数据量很大,我们可以试试data.table的non-equi join:

    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
    

    这里,y 中的label 是来自alabel,而label.i 是来自blabel

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

    library(data.table)
    setDT(a)
    setDT(b)
    
    a[, label2 := label - 2]
    y <- a[
        b,
        .(user, label.a = label, label.b = i.label),
        on = .(user, label2 <= label),
        allow.cartesian=TRUE]
    

    【讨论】:

    • 这当然可以,但我正在寻找一种方法来调整合并本身,因为实际数据很大,在加入后转租太贵了......
    • @ZahiroMor,试试data.table(见我编辑的答案。)
    猜你喜欢
    • 1970-01-01
    • 2019-12-01
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 2014-04-14
    • 1970-01-01
    • 2021-08-08
    相关资源
    最近更新 更多