SHRram
SHRram

Reputation: 4227

how to pass arguments as a list in R function

I have functions that has a lot of arguments. So I would like to create a list of arguments and pass them to the function.

As an example, take ?mean function:

mean(x, trim = 0, na.rm = FALSE, ...)

So lets say I want to calculate mean of 1:10, assigned to variable x, but pass other arguments as a list:

gm <- list (trim = 0, na.rm = FALSE)

mean(1:10, gm)
#R> Error in mean.default(1:10, gm) : 'trim' must be numeric of length one

I tried to use do.call but do not work either.

do.call(mean,list(1:10, gm))
#R> Error in mean.default(1:10, list(trim = 0, na.rm = FALSE)) : 
#R>   'trim' must be numeric of length one

Upvotes: 9

Views: 5767

Answers (3)

Paul
Paul

Reputation: 9087

This can also be done with rlang::exec and the unquote-splice operator, !!!.

rlang::exec(mean, 1:10, !!!gm)
#> [1] 5.5

Upvotes: 1

Benjamin Christoffersen
Benjamin Christoffersen

Reputation: 4841

You can set the default arguments instead which may be convenient if you are doing this repeatedly as an alternative to using do.call. You can do this with formals as follows:

f <- mean.default
formals(f)[match(names(formals(f)), names(gm))] <- gm

f(1:10)
#R> [1] 5.5

This has a few corner cases to watch out for. For one, I use mean.default and not mean as I otherwise have to place the argument from gm before the ....

Another alternative to do.call is to create a call and use eval:

cl <- as.call(c(list(quote(mean), x = 1:10), gm))
cl
#R> mean(x = 1:10, trim = 0, na.rm = FALSE)

eval(cl)
#R> [1] 5.5

Upvotes: 0

sds
sds

Reputation: 60004

As noted in a comment, your gm has the wrong shape for do.call, it interprets your option list as a trim argument.

To make the argument correct shape, use c:

gm <- list(trim=0, na.rm=FALSE)
do.call(mean, c(list(1:10), gm))
[1] 5.5

Upvotes: 1

Related Questions