Reputation: 1107
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
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
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