Функция Dplyr с необязательным аргументом по умолчанию и обязательным многоточием

У меня есть простая функция, которая добавляет счетчики для уникальной комбинации переменных:

Функция

# Add tally summary for group
add_tally <- function(df, n = "n", ...) {
  # Grpup variables
  group_vars <- rlang::quos(...)

  # Check if ellipsis is empty
  if (length(group_vars) == 0) {
    stop("Missing grouping variables")
  }

  none <- Negate(any)

  # Check that passed object is data frame or tibble
  if (none(tibble::is_tibble(df), is.data.frame(df))) {
    stop("Passed object should be a data frame or tibble.")
  }

  if (hasArg("n")) {
    # Take varname
    varname <- n
  } else {
    varname <- "n"
  }

  df %>%
    group_by(!!!group_vars, add = TRUE) %>%
    mutate(!!varname := sum(n())) %>%
    ungroup()

}

Пример

Это довольно просто:

>> mtcars[,c("am", "gear")] %>% add_tally(n = "my_n", am,gear)
# A tibble: 32 x 3
      am  gear  my_n
   <dbl> <dbl> <int>
 1  1.00  4.00     8
 2  1.00  4.00     8
 3  1.00  4.00     8
 4  0     3.00    15
 5  0     3.00    15
 6  0     3.00    15
 7  0     3.00    15
 8  0     4.00     4
 9  0     4.00     4
10  0     4.00     4

Проблема

Я бы хотел, чтобы аргумент n был необязательным. т.е. если явно не определен (как my_n в приведенном выше примере), я бы хотел, чтобы аргумент принимал значение по умолчанию n. Как это обычно бывает с n = "n", который теперь является избыточным из-за попытки вызова hasArgs().

Пример

Это не удается:

>> mtcars[,c("am", "gear")] %>% add_tally(am,gear)
Error in add_tally(., am, gear) : object 'am' not found

Желаемые результаты

# A tibble: 32 x 3
          am  gear  n
       <dbl> <dbl> <int>
     1  1.00  4.00     8
     2  1.00  4.00     8
     3  1.00  4.00     8
     4  0     3.00    15
     5  0     3.00    15
     6  0     3.00    15
     7  0     3.00    15
     8  0     4.00     4
     9  0     4.00     4
    10  0     4.00     4

person Konrad    schedule 22.02.2018    source источник
comment
просто измените порядок ваших параметров add_tally <- function(df, ..., n = "n")   -  person Julien Navarre    schedule 22.02.2018
comment
@JulienNavarre Правильно, если вы хотите сделать это ответом, я буду рад принять.   -  person Konrad    schedule 22.02.2018
comment
@akrun TBH, не так много практических причин для этой функции. Я хочу лучше использовать квазуры и rlang как таковые, там много чего бессмысленного, например none <- Negate(any).   -  person Konrad    schedule 22.02.2018
comment
Связано с этим   -  person akrun    schedule 22.02.2018
comment
@akrun Большое спасибо за информативную ссылку.   -  person Konrad    schedule 22.02.2018


Ответы (1)


Вам нужно изменить порядок ваших параметров, чтобы второй параметр, который вы даете, не интерпретировался как значение n, если он безымянный.

add_tally <- function(df, ..., n = "n") {
 #function code
}
person Julien Navarre    schedule 22.02.2018