子集数据帧,其中值大于另一个数据帧

时间:2017-09-27 21:13:03

标签: r

假设我有一个包含3列数据(a,b,c)的数据框和1列类别,每个类别(类)有多个实例。

$ sbt 'set coverageEnabled := true'...

我有另一个数据框,其中包含相同的3列数据和类别列,但每个类别(类)只有一个实例。

set.seed(273)
a <- floor(runif(20,0,100))
b <- floor(runif(20,0,100))
c <- floor(runif(20,0,100))
class <- floor(runif(20,0,6))

df1 <- data.frame(a,b,c,class)

print(df1)
    a  b  c class
1  31 73 28     3
2  44 33 57     3
3  19 35 53     0
4  68 70 39     4
5  92  7 57     2
6  13 67 23     3
7  73 50 14     2
8  59 14 91     5
9  37  3 72     5
10 27  3 13     4
11 63 28  0     5
12 51  7 35     4
13 11 36 76     3
14 72 25  8     5
15 23 24  6     3
16 15  1 16     5
17 55 24  5     5
18  2 54 39     1
19 54 95 20     3
20 60 39 65     1

如何对第一个数据框进行子集,以便只有a,b和c的行都大于每个类的第二个数据帧中的值?例如,我只想要a <- floor(runif(6,0,20)) b <- floor(runif(6,0,20)) c <- floor(runif(6,0,20)) class <- seq(0,5) df2 <- data.frame(a,b,c,class) print(df2) a b c class 1 8 15 13 0 2 0 3 6 1 3 14 4 0 2 4 7 10 6 3 5 18 18 16 4 6 17 17 11 5 class == 0的行。

请注意,我不想加入数据帧,因为第二个数据帧是第一个数据帧的最低可接受值。

1 个答案:

答案 0 :(得分:3)

正如Frank评论的那样,可以使用 non-equi 连接来完成。

    # coerce to data.table
tmp <- setDT(df1)[
  # non-equi join to find which rows of df1 fulfill conditions in df2
  setDT(df2), on = .(class, a > a, b > b, c > c), rn, nomatch = 0L, which = TRUE]

# return subset in original order of df1
df1[sort(tmp)]
     a  b  c class
 1: 31 73 28     3
 2: 44 33 57     3
 3: 19 35 53     0
 4: 68 70 39     4
 5: 92  7 57     2
 6: 13 67 23     3
 7: 73 50 14     2
 8: 11 36 76     3
 9:  2 54 39     1
10: 54 95 20     3
11: 60 39 65     1

参数which = TRUE返回匹配行号的向量,而不是连接的数据集。这样可以避免我们在连接之前创建行id列。 (感谢@Frank提醒我which参数!)

请注意,df1中没有符合class == 5df2条件的行。因此,参数nomatch = 0L用于从结果中排除不匹配的行。

这可以放在“一线”中:

setDT(df1)[sort(df1[setDT(df2), on = .(class, a > a, b > b, c > c), nomatch = 0L, which = TRUE])]