【问题标题】:Use filter in dplyr conditional on an if statement in R在 R 中的 if 语句上使用 dplyr 中的过滤器
【发布时间】:2018-05-17 09:00:29
【问题描述】:

让我分享一个我正在尝试做的示例,因为标题可能不像我希望的那样清晰。这没有可重现的代码,但如果有帮助,我可以添加一个可重现的示例:

library(dplyr)
if(this_team != "") {
  newdf <- mydf %>%    
      filter(team == this_team) %>%
      mutate(totalrows = nrow(.)) %>%
      group_by(x1, y1) %>%
      summarize(dosomestuff)
} else {
  newdf <- mydf %>%    
      filter(firstname == this_name & lastname == that_name) %>%
      mutate(totalrows = nrow(.)) %>%
      group_by(x1, y1) %>%
      summarize(dosomestuff)
}

我正在 R 中创建一个函数,该函数对 mydf 数据帧进行一些数据操作。如果我将值传递给函数的 team_name 参数,那么我想使用“团队”列过滤数据框。如果我不将值传递给 team_name 参数,则默认为 "",我改为传递 this_name 和 that_name 的值,它们对应于 mydf 中的 'firstname' 和 'lastname' 列。

有没有更好的方法来做到这一点,而不必在两个单独的 if else 语句中再次创建整个 dplyr 管道?我的实际代码流水线每条都超过 4 行,因此必须重现这样的代码非常令人沮丧。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    根据 lukeA 的评论,您也可以使用case_when()

    library(dplyr)
    y <- ""
    data.frame(x = 1:5) %>% 
      filter(case_when(y=="" ~ x > 3, #When y == "", x > 3
                       T ~ x<3) #Otherwise, x < 3
             ) %>% 
      tail(1)
    

    如果您有两个以上的条件要评估,这会更好。

    【讨论】:

      【解决方案2】:

      看看下面的代码是否有效,我们在filter 语句中插入if-else 条件。这是有道理的,因为后面的语句接受一个逻辑语句作为其输入——我们只是使用前面的语句来控制输入的值。

      library(dplyr)
      
      newdf <- mydf %>%    
        filter(
          if (this_team != "") {
            team == this_team
          } else {
            firstname == this_name & lastname == that_name
          }
        ) %>%
        mutate(totalrows = nrow(.)) %>%
        group_by(x1, y1) %>%
        summarize(dosomestuff)
      

      【讨论】:

      • 我观察到,在您只想返回未过滤数据的情况下,您可以像这样设置 if else data %&gt;% filter( if (this_team != "") { team == this_team } else { team == team })else 表示用户没有选择任何过滤条件并且不想过滤。
      【解决方案3】:

      你可以的

      library(dplyr)
      y <- ""
      data.frame(x = 1:5) %>% 
        {if (y=="") filter(., x>3) else filter(., x<3)} %>% 
        tail(1)
      

      data.frame(x = 1:5) %>% 
       filter(if (y=="") x>3 else x<3) %>%  
        tail(1)
      

      甚至将您的烟斗存放在血管中

      mypipe <- . %>% tail(1) %>% print
      data.frame(x = 1:5) %>% mypipe
      

      【讨论】:

      • 没有意识到它是如此简单,因为我认为我不能简单地将 if() 语句放在管道中间。谢谢!
      • 很好的解决方案。只有一个问题:为什么即使在既没有输入 if 也没有输入 else 子句的情况下也能这样做? dplyr 然后通过双管道运算符但没有抱怨 - 但为什么??
      • 值得注意的是,过滤语句中的if语句需要有else子句,否则报错
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多