I keep running into this issue with functions in R where, if an argument (to a sub-function) is passed via ... that has a name that is a substring of an argument to the main function, R will use the ... argument for the main function argument, even when the main function argument has a default value:
Here's a simple example:
myfunc <- function(a, b_longer = NULL, ...) {
print(paste("a =", a))
if(!is.null(b_longer)) {print(paste("b_longer =", b_longer))}
if(length(list(...)) > 0) {print("... args detected")}
}
When I run:
> myfunc(a = 5, b_longer = 5)
[1] "a = 5"
[1] "b_longer = 5"
> myfunc(a = 5, c = "hello")
[1] "a = 5"
[1] "... args detected"
> myfunc(a = 5, b = "hello")
[1] "a = 5"
[1] "b_longer = hello"
This works as long as the ... argument's name continues to be a substring of the main function argument's name, and doesn't appear to have anything to do with the underscore:
> myfunc(a = 5, b_ = "hello")
[1] "a = 5"
[1] "b_longer = hello"
> myfunc(a = 5, b_l = "hello")
[1] "a = 5"
[1] "b_longer = hello"
> myfunc(a = 5, b_lg = "hello")
[1] "a = 5"
[1] "... args detected"
This is the same outcome when the default value is NA and not NULL:
myfunc2 <- function(a, b_longer = NA, ...) {
print(paste("a =", a))
if(!is.na(b_longer)) {print(paste("b_longer =", b_longer))}
if(length(list(...)) > 0) {print("... args detected")}
}
When I run:
> myfunc2(a = 5, b_longer = 5)
[1] "a = 5"
[1] "b_longer = 5"
> myfunc2(a = 5, c = "hello")
[1] "a = 5"
[1] "... args detected"
> myfunc2(a = 5, b = "hello")
[1] "a = 5"
[1] "b_longer = hello"
> myfunc2(a = 5, b_ = "hello")
[1] "a = 5"
[1] "b_longer = hello"
> myfunc2(a = 5, b_l = "hello")
[1] "a = 5"
[1] "b_longer = hello"
> myfunc2(a = 5, b_lg = "hello")
[1] "a = 5"
[1] "... args detected"
Anyone have any pointers for why this would be happening? Is this default R behavior? If so, why???
I've reproduced the behavior above, and am trying to figure out if this is simply a general behavior of R that I need work around by carefully naming my function arguments so that they are not superstrings of any of the possible arguments to be passed via ..., or if there's some other way to code things that prevents this sort of mis-variable assignment