Условие if / else в функции dplyr 0.7 - PullRequest
0 голосов
/ 30 июня 2018

Я бы хотел сделать простое условие if / else в функции dplyr. Я просмотрел несколько полезных постов (например, Как параметризовать вызовы функций в dplyr 0.7? ), но все еще сталкиваюсь с проблемами.

Ниже приведен игрушечный пример, который работает, когда я вызываю функцию без переменной группировки. Затем функция завершается ошибкой с переменной группировки.

# example dataset
test <- tibble(
  A = c(1:5,1:5),
  B = c(1,2,1,2,3,3,3,3,3,3),
  C = c(1,1,1,1,2,3,4,5,4,3)
)

# begin function, set default for group var to NULL.
prop_tab <- function(df, column, group = NULL) {

  col_name <- enquo(column)
  group_name <- enquo(group)

  # if group_by var is NOT null, then...
  if(!is.null(group)) {
      temp <- df %>%
        select(!!col_name, !!group_name) %>% 
        group_by(!!group_name) %>% 
        summarise(Percentages = 100 * length(!!col_name) / nrow(df))

  } else {
  # if group_by var is null, then...
      temp <- df %>%
        select(!!col_name) %>% 
        group_by(col_name = !!col_name) %>% 
        summarise(Percentages = 100 * length(!!col_name) / nrow(df)) 

  }

  temp
}

test %>% prop_tab(column = C)  # works

test %>% prop_tab(column = A, group = B)  # fails
# Error in prop_tab(., column = A, group = B) : object 'B' not found

Ответы [ 3 ]

0 голосов
/ 30 июня 2018

Проблема в том, что когда вы указываете аргументы без кавычек, is.null не знает, что с этим делать. Таким образом, этот код пытается проверить, является ли объект B нулевым и нет ли ошибок, поскольку B не существует в этой области. Вместо этого вы можете использовать missing(), чтобы проверить, был ли передан аргумент функции, например, так. Возможно, есть более чистый путь, но это, по крайней мере, работает, как вы можете видеть внизу.

library(tidyverse)
test <- tibble(
  A = c(1:5,1:5),
  B = c(1,2,1,2,3,3,3,3,3,3),
  C = c(1,1,1,1,2,3,4,5,4,3)
)

# begin function, set default for group var to NULL.
prop_tab <- function(df, column, group) {

  col_name <- enquo(column)
  group_name <- enquo(group)

  # if group_by var is not supplied, then:
  if(!missing(group)) {
    temp <- df %>%
      select(!!col_name, !!group_name) %>%
    group_by(!!group_name) %>%
    summarise(Percentages = 100 * length(!!col_name) / nrow(df))

  } else {
    # if group_by var is null, then...
    temp <- df %>%
      select(!!col_name) %>% 
      group_by(col_name = !!col_name) %>% 
      summarise(Percentages = 100 * length(!!col_name) / nrow(df)) 

  }

  temp
}

test %>% prop_tab(column = C)  # works
#> # A tibble: 5 x 2
#>   col_name Percentages
#>      <dbl>       <dbl>
#> 1        1          40
#> 2        2          10
#> 3        3          20
#> 4        4          20
#> 5        5          10

test %>% prop_tab(column = A, group = B)
#> # A tibble: 3 x 2
#>       B Percentages
#>   <dbl>       <dbl>
#> 1     1          20
#> 2     2          20
#> 3     3          60

Создано в 2018-06-29 пакетом Представить (v0.2.0).

0 голосов
/ 30 июня 2018

Вы можете использовать missing вместо is.null, чтобы ваш аргумент не оценивался (именно это и привело к ошибке):

prop_tab <- function(df, column, group = NULL) {

  col_name <- enquo(column)
  group_name <- enquo(group)

  # if group_by var is NOT null, then...
  if(!missing(group)) {
    temp <- df %>%
      select(!!col_name, !!group_name) %>% 
      group_by(!!group_name) %>% 
      summarise(Percentages = 100 * length(!!col_name) / nrow(df))

  } else {
    # if group_by var is null, then...
    temp <- df %>%
      select(!!col_name) %>% 
      group_by(col_name = !!col_name) %>% 
      summarise(Percentages = 100 * length(!!col_name) / nrow(df)) 

  }

  temp
}

test %>% prop_tab(column = C) 
# example dataset
# # A tibble: 5 x 2
#   col_name Percentages
#      <dbl>       <dbl>
# 1        1          40
# 2        2          10
# 3        3          20
# 4        4          20
# 5        5          10

test %>% prop_tab(column = A, group = B)
# # A tibble: 3 x 2
#       B Percentages
#   <dbl>       <dbl>
# 1     1          20
# 2     2          20
# 3     3          60

Вы также можете использовать length(substitute(group)) вместо !missing(group), это будет более надежным, так как не потерпит неудачу в маловероятном случае, когда кто-то явно заполняет групповой аргумент с помощью NULL (предыдущая опция вылетит в это дело).

0 голосов
/ 30 июня 2018

Одним из вариантов будет проверка «group_name» вместо «group»

prop_tab <- function(df, column, group = NULL) {

  col_name <- enquo(column)
  group_name <- enquo(group)

  # if group_by var is NOT null, then...
  if(as.character(group_name)[2] != "NULL") {
      temp <- df %>%
        select(!!col_name, !!group_name) %>% 
        group_by(!!group_name) %>% 
        summarise(Percentages = 100 * length(!!col_name) / nrow(df))

  } else {
  # if group_by var is null, then...
      temp <- df %>%
        select(!!col_name) %>% 
        group_by(col_name = !!col_name) %>% 
        summarise(Percentages = 100 * length(!!col_name) / nrow(df)) 

  }

  temp
}

-Проверка

prop_tab(test, column = C, group = B)
# A tibble: 3 x 2
#<     B Percentages
# <dbl>       <dbl>
#1     1          20
#2     2          20
#3     3          60  



prop_tab(test, column = C)
# A tibble: 5 x 2
#  col_name Percentages
#     <dbl>       <dbl>
#1        1          40
#2        2          10
#3        3          20
#4        4          20
#5        5          10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...