TobiSonne
TobiSonne

Reputation: 1107

Default argument to function only if condition is met

I am currently writing a function that I want to pass default arguments if a condition is met. If the condition is not met, no argument should be passed. How can I achieve this? I tried it with ifelse and NULL like in this minimal example but it did not work:

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

If "var1" is no variable name of .data and I don't pass another argument on .variable, I want to get an error like "argument ".variable" is missing, with no default". My solution works but I get other error messages.

Upvotes: 2

Views: 1111

Answers (2)

Julius Vainora
Julius Vainora

Reputation: 48191

It seems that ifelse doesn't like having NULL as the response in the case the condition is 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

It seems to come from the fact that ifelse returns

A vector of the same length and attributes (including dimensions and "class") as test and data values from the values of yes or no.

and

If yes or no are too short, their elements are recycled.

Seeing rep in the error message and the fact that length(NULL) is zero seems to be a good evidence. So, instead you may want to use, e.g.,

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

my_function("1")
# [1] TRUE

See ?ifelse for other warnings.

Upvotes: 2

Jack Aidley
Jack Aidley

Reputation: 20107

I would suggest not doing it directly in the default argument, but at the start of the function, with something along the lines of:

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

Upvotes: 0

Related Questions