do.call
is limited by the same restrictions you are when calling a function. By taking all the formals and readding them, you are essentially calling
ranger(formula = Species ~ ., data = iris, num.trees = 500,
mtry = NULL, importance = "none", write.forest = TRUE, probability = FALSE,
min.node.size = NULL, max.depth = NULL, replace = TRUE, sample.fraction = ifelse(replace,
1, 0.632), case.weights = NULL, class.weights = NULL,
splitrule = NULL, num.random.splits = 1, alpha = 0.5, minprop = 0.1,
split.select.weights = NULL, always.split.variables = NULL,
respect.unordered.factors = NULL, scale.permutation.importance = FALSE,
local.importance = FALSE, regularization.factor = 1, regularization.usedepth = FALSE,
keep.inbag = FALSE, inbag = NULL, holdout = FALSE, quantreg = FALSE,
oob.error = TRUE, num.threads = NULL, save.memory = FALSE,
verbose = TRUE, seed = NULL, dependent.variable.name = NULL,
status.variable.name = NULL, classification = NULL, x = NULL,
y = NULL)
And you get the exact same error if you run that. Let's create a simplified example
foo <- function(x, y=x+5) {
x*y
}
foo(5)
# [1] 50
If I tried the same trick, I would get
params <- as.list(formals(foo))
params$x <- 5
do.call("foo", params)
# Error in foo(x = 5, y = x + 5) : object 'x' not found
because I cannot call
foo(x =5, y=x+5)
Default lazy parameter values are kind of special. There's nothing you can pass to them that will behave like if you leave the value missing. That's because values you pass in are evaluated in a different environment than default parameters. The specific error you get " cannot coerce type 'closure' to vector of type 'logical'" is because replace
is a function in the global enviroment, but has a different meaning within the function itself.
If you want to avoid potential problems, it's probably best not to start with all the formal arguments. Or at the very list filter out any calls or symbols. You could filter them out with
lParams <- lParams[!sapply(lParams, function(x) any(c("call","symbol") %in% class(x)))]