Home > Mobile >  R: Passing named function arguments from vector
R: Passing named function arguments from vector

Time:04-29

How can I achieve that I can pass named function arguments from a named vector?

vec <- c(b=5, a=3)
fun <- function(a, b) {
  browser()
  message(sprintf("a=%s", a))
  message(sprintf("b=%s", b))
}
fun(vec) # should return a=3, b=5

I mean in this example, I want to dynmically pass the values from vec into fun without doing a=vec$a, b=vec$b?

CodePudding user response:

In base R we can use eval(bquote()) with ..() and splice = TRUE.

In {rlang} we can use inject with !!! instead.

Alternatively to the existing do.call() answer (see above) {rlang} has exec() which takes also an atomic vector instead of a list.

vec <- c(b = 5,  a = 3)

fun <- function(a, b) {
  message(sprintf("a=%s", a))
  message(sprintf("b=%s", b))
}

# base R
eval(bquote(fun(..(vec)), splice = TRUE)) 
#> a=3
#> b=5

# rlang
rlang::inject(fun(!!! vec))
#> a=3
#> b=5

# rlang
rlang::exec(fun, !!! vec)
#> a=3
#> b=5

Created on 2022-04-28 by the reprex package (v2.0.1)

CodePudding user response:

There are a few ways to do this in R, but typically you will need to convert your named vector to a named list using as.list at some point.

For example using with :

with(as.list(vec), {
  fun(a, b)
})
#> a=3
#> b=5

Or do.call

do.call(fun, as.list(vec))
#> a=3
#> b=5

If you are using the function frequently and want to avoid the boilerplate, another option is to use a wrapper function to make it easy to call by just passing vec

f <- function(v) eval(as.call(c(quote(fun), as.list(v))))

f(vec)
#> a=3
#> b=5

Note that $ can't be used to subset named vectors, so your can't even do fun(a = vec$a, b = vec$b) ; you would need to do fun(a = vec['a'], b = vec['b']). Using $ requires a list, a data.frame or an environment

CodePudding user response:

Do you mean this?

vec <- c(b=5, a=3)
fun <- function(v) {
  browser()
  message(sprintf("a=%s", v['a']))
  message(sprintf("b=%s", v['b']))
}
fun(vec) # should return a=3, b=5

Output:

> fun(vec) # should return a=3, b=5
Called from: fun(vec)
Browse[1]> 
debug at #3: message(sprintf("a=%s", v["a"]))
Browse[2]> 
a=3
debug at #4: message(sprintf("b=%s", v["b"]))
Browse[2]> 
b=5
> 
  • Related