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

时间:2015-03-16 13:28:25

标签: r subset

我有两个数据框:

  • df单个x的位置有多个值y
  • matchDf定义了我想用来过滤df
  • 的约束

我希望仅过滤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)'
      )

2 个答案:

答案 0 :(得分:4)

试试这个:

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正在matchDf dfy中的哪一行应该在哪一行。然后,您只需将其用作位置行提取向量,并且使用<=陈述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] 的工作原理,请将其从表达式中删除:

[

级别标签无关紧要,因为{{1}}使用基础整数值来提取。

答案 1 :(得分:3)

你可以这样做:

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值,并应用于每个“情侣” df并返回TRUEFALSE,然后根据df结果对mapply进行子集化。