假设我有一个包含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
的行。
请注意,我不想加入数据帧,因为第二个数据帧是第一个数据帧的最低可接受值。
答案 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 == 5
中df2
条件的行。因此,参数nomatch = 0L
用于从结果中排除不匹配的行。
这可以放在“一线”中:
setDT(df1)[sort(df1[setDT(df2), on = .(class, a > a, b > b, c > c), nomatch = 0L, which = TRUE])]