在另一个数据框中,选取数值大于当前数据框的子集。

3

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

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

我有另一个数据框,与前面提到的数据框相同,包含3列数据和分类列,但每个分类(类别)只有一个实例。

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

如何对第一个数据框进行子集操作,以便仅保留每个类别中a、b和c均大于第二个数据框中的值的行?例如,如果class == 0a > 8 & b > 15 & c > 13,则只想要这些行。
请注意,我不想合并数据框,因为第二个数据框是第一个数据框中最低可接受值。

1
谢谢Frank,我已经添加了一个可重现的例子。 - thebigmcrae
1个回答

3
如 Frank 所评论的那样,这可以通过 非等值联接 来完成。
    # 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参数!)请注意,在df2中没有一行满足class == 5的条件,因此使用参数nomatch = 0L从结果中排除非匹配行。这可以组合成一个“一行代码”:
setDT(df1)[sort(df1[setDT(df2), on = .(class, a > a, b > b, c > c), nomatch = 0L, which = TRUE])]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接