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
>