Аргумент по умолчанию для функции, только если условие выполнено - PullRequest
0 голосов
/ 07 декабря 2018

В настоящее время я пишу функцию, в которую я хочу передать аргументы по умолчанию, если выполняется условие.Если условие не выполняется, аргумент не должен передаваться.Как мне этого добиться?Я попробовал это с ifelse и NULL, как в этом минимальном примере, но это не сработало:

my_function <- function(.data,
                        .variable = ifelse("var1" %in% names(.data), "var1", NULL)){
  ...
}

Если «var1» не является именем переменной .data, и я не передаю другой аргумент для .variable,Я хочу получить ошибку типа «аргумент». Переменная отсутствует, без значения по умолчанию ».Мое решение работает, но я получаю другие сообщения об ошибках.

Ответы [ 2 ]

0 голосов
/ 07 декабря 2018

Я бы предложил делать это не напрямую в аргументе по умолчанию, а в начале функции, что-то вроде:

my_function <- function(.data,
                        .variable = NULL) {
  if (is.null(.variable)) {
    if ("var1" %in% names(.data)) {
      .variable = "var1" 
    } else {
      stop(".variable undefined with no suitable default")
    }
  }
  ...
}
0 голосов
/ 07 декабря 2018

Кажется, что ifelse не нравится иметь NULL в качестве ответа в случае, если условие FALSE:

ifelse(2 < 1, 1, NULL)
# Error in ans[!test & ok] <- rep(no, length.out = length(ans))[!test &  : 
#   replacement has length zero
# In addition: Warning message:
# In rep(no, length.out = length(ans)) :
#   'x' is NULL so the result will be NULL

Кажется, это происходит из-за того, что ifelseвозвращает

Вектор такой же длины и атрибутов (включая измерения и «класс»), что и значения тестов и данных из значений да или нет.

и

Если да или нет слишком короткие, их элементы перерабатываются.

Если в сообщении об ошибке указано rep и то, что length(NULL) равно нулю, похоже,хорошее доказательство.Таким образом, вместо этого вы можете использовать, например,

my_function <- function(.data, .variable = if("var1" %in% names(.data)) "var1" else NULL)
  is.null(.variable)

my_function("1")
# [1] TRUE

См. ?ifelse для других предупреждений.

...