根据另一个数据框中的多个条件过滤数据框

Filter data frame based on multiple conditions in another data frame

我有两个数据框:

我只想过滤 y 小于或等于 max_y 的行,因为 x 属于区间 <x_from, x_to)

有没有办法在 R 中做到这一点(没有 SQL 我在下面使用)?

df <- read.table(header = TRUE, text = '
x y
100 0.1
100 0.2
100 0.3
250 0.2
250 0.3
250 0.4
375 0.2
375 0.25
375 0.35
420 0.15
420 0.16
420 0.17
500 0.23
500 0.55')

matchDf <- read.table(header = TRUE, text = '
x_from x_to max_y
0 300 .2
300 500 .3
500 99999 .5
')

library(sqldf)

sqldf('select a.* 
      from 
        df a 
        join matchDf b on (a.x >= b.x_from 
                           and a.x < b.x_to 
                           and a.y <= b.max_y)'
      )

你可以这样做:

df[mapply(function(x, y) {
               y <= matchDf$max_y[x >=matchDf$x_from  & x < matchDf$x_to]
            }, x=df$x, y=df$y), ]
     # x    y
# 1  100 0.10
# 2  100 0.20
# 4  250 0.20
# 7  375 0.20
# 8  375 0.25
# 10 420 0.15
# 11 420 0.16
# 12 420 0.17
# 13 500 0.23

函数 mapply 允许,对于每对 (x,y),知道 y 是否低于或等于适当的 max_y 值,并应用于每个 "couple" 的 df 和 return TRUEFALSE,然后 df 根据 mapply 结果进行子集化。

试试这个:

df[df$y <= matchDf$max_y[cut(df$x, c(0,matchDf$x_to))],]
     x    y
1  100 0.10
2  100 0.20
4  250 0.20
7  375 0.20
8  375 0.25
10 420 0.15
11 420 0.16
12 420 0.17
13 500 0.23

这里发生的事情是 cut 为您提供 df 中的每个观察值应该在 matchDf 中的哪一行。然后,您只需将其用作位置行提取向量, 并使用 <=.

陈述 y 的条件关系

要查看 cut 的工作原理,只需将其从表达式中拉出即可:

> cut(df$x, c(0,matchDf$x_to))
 [1] (0,300]   (0,300]   (0,300]   (0,300]   (0,300]   (0,300]   (300,500] (300,500] (300,500] (300,500] (300,500] (300,500] (300,500] (300,500]
Levels: (0,300] (300,500] (500,1e+05]

级别标签无关紧要,因为 [ 使用基础整数值进行提取。