R:从向量传递命名函数参数
R: Passing named function arguments from 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
我的意思是在这个例子中,我想动态地将值从 vec
传递到 fun
而无需执行 a=vec$a
、b=vec$b
?
你是这个意思吗?
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
输出:
> 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
>
在 R 中有几种方法可以做到这一点,但通常您需要将命名的 vector 转换为命名的 list在某些时候使用 as.list
。
例如使用with
:
with(as.list(vec), {
fun(a, b)
})
#> a=3
#> b=5
或do.call
do.call(fun, as.list(vec))
#> a=3
#> b=5
如果您经常使用该函数并希望避免样板文件,另一种选择是使用包装函数,只需传递 vec
即可轻松调用
f <- function(v) eval(as.call(c(quote(fun), as.list(v))))
f(vec)
#> a=3
#> b=5
注意 $
不能用于子集命名向量,所以你不能 even 做 fun(a = vec$a, b = vec$b)
;你需要做 fun(a = vec['a'], b = vec['b'])
。使用 $
需要 list
、data.frame
或 environment
在基础 R 中,我们可以将 eval(bquote())
与 ..()
和 splice = TRUE
一起使用。
在 {rlang} 中,我们可以使用 inject
代替 !!!
。
替代现有的 do.call()
答案(见上文){rlang} 有 exec()
它也采用原子向量而不是列表。
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
由 reprex package (v2.0.1)
于 2022-04-28 创建
我怎样才能实现从命名向量传递命名函数参数?
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
我的意思是在这个例子中,我想动态地将值从 vec
传递到 fun
而无需执行 a=vec$a
、b=vec$b
?
你是这个意思吗?
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
输出:
> 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
>
在 R 中有几种方法可以做到这一点,但通常您需要将命名的 vector 转换为命名的 list在某些时候使用 as.list
。
例如使用with
:
with(as.list(vec), {
fun(a, b)
})
#> a=3
#> b=5
或do.call
do.call(fun, as.list(vec))
#> a=3
#> b=5
如果您经常使用该函数并希望避免样板文件,另一种选择是使用包装函数,只需传递 vec
f <- function(v) eval(as.call(c(quote(fun), as.list(v))))
f(vec)
#> a=3
#> b=5
注意 $
不能用于子集命名向量,所以你不能 even 做 fun(a = vec$a, b = vec$b)
;你需要做 fun(a = vec['a'], b = vec['b'])
。使用 $
需要 list
、data.frame
或 environment
在基础 R 中,我们可以将 eval(bquote())
与 ..()
和 splice = TRUE
一起使用。
在 {rlang} 中,我们可以使用 inject
代替 !!!
。
替代现有的 do.call()
答案(见上文){rlang} 有 exec()
它也采用原子向量而不是列表。
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
由 reprex package (v2.0.1)
于 2022-04-28 创建