【问题标题】:dplyr filter() inside of function with optional variables (filter_if maybe?)带有可选变量的函数内部的 dplyr filter() (filter_if 也许?)
【发布时间】:2023-03-27 09:13:02
【问题描述】:

我正在尝试编写函数,该函数将根据一些可选的用户变量执行过滤,以在绘制过滤或未过滤数据之前对输入数据进行阈值处理。在此示例中,data 是具有多个列的 data.frame,其中包括两个感兴趣的列(var1var2):

example_func <- function(
  data,
  low_cutoff_var1 = NULL,
  high_cutoff_var1 = NULL,
  low_cutoff_var2 = NULL,
  high_cutoff_var2 = NULL) {
...
}

现在,作为此功能的一部分,如果用户在绘制数据之前提供了输入data,我想过滤输入data(根据用户选择过滤或未过滤)。过滤步骤是:

data_filtered <- data %>% 
  filter(var1 > low_cutoff_var1 &
         var1 < high_cutoff_var1 &
         var2 > low_cutoff_var2 &
         var2 < high_cutoff_var2)

但是,问题是如果一个或多个截止值是NULL,那么过滤器就不起作用。

现在我知道可以一步一步地为每个截止时间做一些事情。 即:

if (!is.null(x = low_cutoff_var1) {
  data_filtered <- data %>% 
    filter(var1 > low_cutoff_var1)
}
if (!is.null(x = high_cutoff_var1) {
etc

但是,这似乎不优雅,并且可能有更好的方法来编写此函数。我觉得filter_if 可能是正确的选择,但我在语法以及如何在我的特定情况下使用时遇到了问题。

任何关于更简单的方法来完成我正在尝试做的事情的建议都会很棒!

谢谢! 山姆

【问题讨论】:

    标签: r function dplyr filtering tidyverse


    【解决方案1】:

    不要使用 NULL 作为默认值,而是使用 -Inf 和 Inf。

    example_func <- function(data,
        low_cutoff_var1 = -Inf, high_cutoff_var1 = Inf,
        low_cutoff_var2 = -Inf, high_cutoff_var2 = Inf) {
      data %>% 
        filter(between(var1, low_cutoff_var1, high_cutoff_var1),
               between(var2, low_cutoff_var2, high_cutoff_var2))
      
    }
    

    【讨论】:

      【解决方案2】:

      这是一种可能的方法:

      example_func <- function(
          data,
          low_cutoff_var1 = NULL,
          high_cutoff_var1 = NULL,
          low_cutoff_var2 = NULL,
          high_cutoff_var2 = NULL) {
          
          arg_values <- match.call()
          filter_funs <- rlang::exprs(
              var1 > low_cutoff_var1, var1 < high_cutoff_var1,
              var2 > low_cutoff_var2, var2 < high_cutoff_var2
          )
          filter_funs <- filter_funs[!sapply(arg_values, is.null)[3:6]]
          
          data_filtered <- data %>% filter(!!!filter_funs)
          return(data_filtered)
      }
      

      一些测试:

      library(dplyr)
      data <- tibble(var1 = c(1, 2, 3), var2 = c(4, 5, 6))
      example_func(data, 1, 3, 4, 6)
      # # A tibble: 1 x 2
      #    var1  var2
      #   <dbl> <dbl>
      # 1     2     5
      example_func(data, NULL, 4, 3, 6)
      # # A tibble: 2 x 2
      #    var1  var2
      #   <dbl> <dbl>
      # 1     1     4
      # 2     2     5
      example_func(data, NULL, NULL, NULL, 6)
      # # A tibble: 2 x 2
      #    var1  var2
      #   <dbl> <dbl>
      # 1     1     4
      # 2     2     5
      example_func(data, NULL, NULL, NULL, NULL)
      # # A tibble: 3 x 2
      #    var1  var2
      #   <dbl> <dbl>
      # 1     1     4
      # 2     2     5
      # 3     3     6
      

      【讨论】:

      • 谢谢!我认为发布的其他解决方案在简化代码方面效果更好,但非常感谢!
      猜你喜欢
      • 2019-06-14
      • 2018-07-14
      • 2018-12-23
      • 2021-02-16
      • 1970-01-01
      • 2019-11-27
      • 1970-01-01
      • 2022-11-02
      • 2021-04-16
      相关资源
      最近更新 更多