Reputation: 2759
In python you can do:
val = [1, 2, 3]
def f(a, b, c):
return(a+b+c)
f(*val)
>>>6
But is there an R equivalent to passing a list/vector to a function and having it unpack the list/vector as the arguments to the function?
val <- c(1, 2, 3)
f <- function(a,
b,
c) {
a+b+c
}
#f(*val)
Upvotes: 4
Views: 794
Reputation: 269965
do.call In R it is do.call
. The first argument is the function or a character string giving the name of the function and the second argument is a list whose components will be passed as individual arguments to the function. No packages are used.
val <- c(1, 2, 3)
f <- function(a, b, c) a+b+c
do.call("f", as.list(val))
## [1] 6
Reduce Another approach is to curry f
creating a new function with the first argument fixed, repeatedly doing so using Reduce
to handle each successive argument. No packages are used.
Reduce(function(f, x, ...) function(...) f(x, ...), val, init = f)()
## [1] 6
invoke The purrr package has invoke
which basically just calls do.call
but it will also convert the second argument to a list if it is not already a list:
library(purrr)
invoke(f, val)
## [1] 6
lift purrr also has lift
which will convert a function that takes individual arguments to a new function that takes a list or vector. It also wraps do.call
lift(f)(val)
## [1] 6
partial purrr also has partial
which will curry the function creating a new function with the first argument fixed taking only the remaining arguments so using reduce
(also in purrr) to repeatedly invoke such currying:
reduce(val, partial, .init = f)()
## [1] 6
Curry Curry
from the functional package could also be used to fix the first argument. When used together with Reduce
from base R to repeatedly apply Curry
it gives the same result. Note that Curry
uses do.call
internally.
library(functional)
Reduce(Curry, init = f, val)()
## [1] 6
Upvotes: 11
Reputation: 13701
Another option is to lift the domain of a function using lift()
from the purrr
package. Your definition of f
takes multiple arguments, which in R terms is known as "dots". You can change its signature to accept a vector instead:
f2 <- purrr::lift_dv(f)
f2(val)
## [1] 6
# Or as a one-liner
purrr::lift_dv(f)(val)
Upvotes: 2