创建一个可以处理可能为NA或NULL的参数的函数

时间:2019-03-17 18:59:17

标签: r function dplyr

我将如何处理这种情况?我希望我不必创建一个if-else语句网络。

df = data.frame(One= c(1,2,3), Two= c(4,5,NA), Three= c(7,NA,9))

One  Two  Three
 1    4    7
 2    5    NA
 3    NA   9

然后我对数据进行置换以获得所有可能性:

dfPermuted = df %>%
    expand(One, Two, Three)

我想创建一个函数,将NA(或NULL)作为参数的默认值,但是如果传入数字,也可以过滤数据。例如:

filterFunction = function(data, one = NA, two = NA, three = NA){
    data %>%
        filter(One == one) %>%
        filter(Two == two) %>%
        filter(Three == three)
}

如果将值实际传递给filterFunction(dfPermuted, one = 2, two = 5, three = 9)之类的参数,这将起作用,但是对于所有值均为NA的组合,filterFunction(dfPermuted)会返回没有结果的数据帧。

我试了一下

filterFunctionFailure = function(data, one = NA, two = NA, three = NA) {
    data %>%
        filter(ifelse(is.na(one), is.na(One), One == one)) %>%
        ...
}

那没有用。

2 个答案:

答案 0 :(得分:0)

这是一种解决方案。我首先评估输入是否为NA,然后构建要过滤的表达式,然后应用过滤器。

library(tidyverse)
library(rlang)

df <-  data.frame(One= c(1,2,3), Two= c(4,5,NA), Three= c(7,NA,9))
dfPermuted <- df %>%
    expand(One, Two, Three)
dfPermuted
#> # A tibble: 27 x 3
#>      One   Two Three
#>    <dbl> <dbl> <dbl>
#>  1     1     4     7
#>  2     1     4     9
#>  3     1     4    NA
#>  4     1     5     7
#>  5     1     5     9
#>  6     1     5    NA
#>  7     1    NA     7
#>  8     1    NA     9
#>  9     1    NA    NA
#> 10     2     4     7
#> # … with 17 more rows

filterFunction <- function(data, one, two, three){

  exp1 <- ifelse(is.na(one), "is.na(One)", paste0("One==", one))
  exp2 <- ifelse(is.na(two), "is.na(Two)", paste0("Two==", two))
  exp3 <- ifelse(is.na(three), "is.na(Three)", paste0("Three==", three))

  exp1 <- rlang::parse_expr(exp1)
  exp2 <- rlang::parse_expr(exp2)
  exp3 <- rlang::parse_expr(exp3)

  data_new <- data %>%
    filter(!!exp1 & !!exp2 & !!exp3)

  return(data_new)
}

filterFunction(dfPermuted, one = 1, two = NA, three = NA)
#> # A tibble: 1 x 3
#>     One   Two Three
#>   <dbl> <dbl> <dbl>
#> 1     1    NA    NA

filterFunction(dfPermuted, one = 2, two = NA, three = 9)
#> # A tibble: 1 x 3
#>     One   Two Three
#>   <dbl> <dbl> <dbl>
#> 1     2    NA     9

filterFunction(dfPermuted, one = 2, two = 5, three = 7)
#> # A tibble: 1 x 3
#>     One   Two Three
#>   <dbl> <dbl> <dbl>
#> 1     2     5     7

请注意,没有观察到所有三个变量均为NA,因此我没有举个例子。

答案 1 :(得分:0)

也许您应该尝试

  filterFunction = function(data, one = NA, two = NA, three = NA){
    f_args <- c(one,two,three)
    new_data <- data
    for(i in 1:length(f_args))
    {
      if(is.na(f_args[i]))
      {
        new_data %>% filter(.,is.na(new_data[,i])) -> new_data
      }
      else new_data %>% filter(.,new_data[,i]==f_args[i]) -> new_data
    }
    return(new_data)
  }

我相信它易于扩展和理解