【问题标题】:R - filter data with dplyr using a test conditionR - 使用测试条件使用 dplyr 过滤数据
【发布时间】:2017-01-25 18:12:35
【问题描述】:

我正在尝试根据测试条件使用dplyrfilter 我的数据,但此测试条件可能会根据其他变量而改变。

使用内置的示例数据集cars

data(cars)

我想做这样的事情:

if (foo == 0) {
  test <- speed > 15
} else {
  test <- dist < 50
}
filter(cars, test)

这不起作用。如果我把它改成这样,我可以让它工作:

if (foo == 0) {
  test <- 'cars$speed > 15'
} else {
  test <- 'cars$dist < 50'
}
filter(cars, eval(parse(text = test)))

但是

  1. 必须输入cars$speedcars$dist 似乎违背了使用filter 函数的目的。
  2. 根据this SO answer,不建议使用eval(parse(text = ...)) 构造。

有没有更好的方法来实现这一点?

【问题讨论】:

    标签: r filter dplyr eval


    【解决方案1】:

    你可以这样做:

    filter(cars, if(foo==0){speed>15}else{dist<50})
    

    通过与简单过滤器比较进行测试:

    > foo =0
    > identical(filter(cars, speed>15), filter(cars, if(foo==0){speed>15}else{dist<50}))
    [1] TRUE
    > foo =1
    > identical(filter(cars, dist<50), filter(cars, if(foo==0){speed>15}else{dist<50}))
    [1] TRUE
    

    filter 语句放在大括号内可能会更简单、更整洁:

    if (foo == 0) {
      filter(cars, speed > 15)
    } else {
      filter(cars, dist < 50)
    }
    

    注意如果你想在某处分配结果,if 返回值:

    > ff = if (foo == 0) {
           filter(cars, speed > 15)
         } else {
           filter(cars, dist < 50)
         }
    > identical(ff, filter(cars, speed>15))
    [1] FALSE
    > identical(ff, filter(cars, dist<50))
    [1] TRUE
    > foo
    [1] 1
    

    【讨论】:

      【解决方案2】:

      这对我有用:

      library(dplyr)
      
      if (foo == 0) {
        test <- cars$speed > 15
      } else {
        test <- cars$dist < 50
      }
      
      filter(cars, test)
      

      我认为使用cars$speedcars$dist 没有问题,因为您使用的是filter。另外,你真的需要使用filter吗?有一种替代方法可以使用 base R 来执行此操作。将最后一行替换为:

      cars[test,]
      

      【讨论】:

      • 谢谢!我同意 cars[test,] 对于这种情况来说是一个更好的解决方案 - 这是一个简单的例子,因为这个问题的代码最少 sn-p。出于某种原因,当我尝试将其嵌入到一个接受 df、列和值并返回过滤结果集的函数中时,这对我不起作用。但实际上它现在似乎正在使用这种逻辑。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 2019-08-26
      • 2018-06-23
      • 1970-01-01
      • 2021-02-27
      • 1970-01-01
      相关资源
      最近更新 更多