I'm trying to use the train function in the caret package, the code for which is here. Here's a very simple example of it working properly:
train(y ~ ., data=X, na.action=na.fail)
Error in na.fail.default(list(y = c(1L, 1L, 2L, 1L, 2L, 1L, 1L, 2L, 1L, :
missing values in object
It is expected in this case that this will fail as my data does have missing values, but the actual problem I'm trying to address is getting the same behavior, i.e. getting to this point of failure, with the following code:
lst <- list(form=y ~ ., data=X, na.action=na.fail)
do.call(train, lst)
Error in as.character(call_obj$na.action) :
cannot coerce type 'closure' to vector of type 'character'
I can see that this is failing in the function check_na_conflict linked here, but I'm not getting why it works in the first case and not the second.My understanding of do.call is that it should simply convert the values in the list into arguments to pass to train, but evidently that is not the case? And if not is there some other proper way to call a function like this with a list of arguments?
Edit: A simpler example is the following:
> f <- function(na.missing) {
m <- match.call()
print(paste("na.missing =", m$na.missing))
}
> f(na.omit)
[1] "na.missing = na.omit"
> lst <- list(na.missing=na.omit)
> do.call(f, lst)
Error in paste("na.missing =", m$na.missing) :
cannot coerce type 'closure' to vector of type 'character'
I was under the impression that do.call would simply call f with argument na.missing=na.omit, which works when calling directly. Is there a way to get this to work properly with do.call? The reason I want to use do.call in the first place is I want to apply the original function to a list of lists of arguments.
What you are describing is because of your use of
match.call(), rather thando.call(). The purpose ofmatch.call()is:Without using
match.call()Your example does not seem to require
match.call(), in which case, it's easier to directly use the function passed as an argument.Let's define a simple function which takes a vector,
x, and a function,na_missing_funto index the missing values. It will return the vector without the missing values:We can call this as follows:
Similarly, using
do.call(), we can do:If we want to apply this function to a list of vectors, we can use
lapply():With
match.call()If there is a reason that you have to use
match.call(), you can do it but you will need toeval()the argument as in line 947 of thecaretcode that you posted. That is becausem$na_missing_funis of classname, rather than classfunction.You can then use the function
fexactly as above: