Создание функции, которая может обрабатывать аргументы как возможно NA или NULL - PullRequest
0 голосов
/ 17 марта 2019

Как бы я справился с такого рода сценарием?Я надеюсь, что мне не нужно создавать сеть операторов 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 голосов
/ 17 марта 2019

Может быть, вам стоит попробовать

  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)
  }

Легко расширяемый и понятный Я верю

0 голосов
/ 17 марта 2019

Вот одно из решений.Сначала я оцениваю, является ли ввод 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, поэтомуЯ не привел это в качестве примера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...