通过列表将参数传递给函数并忽略未使用的参数
Passing arguments to a function via list and ignoring unused arguments
背景
我对使用 do.call
通过一个列表将参数传递给两个函数很感兴趣。 do.call
解决方案应忽略未使用的参数。
例子
my_sum <- function(a, b) {
a + b
}
my_exp <- function(c, d) {
c^d
}
args_to_use <- as.list(1:4)
names(args_to_use) <- letters[1:4]
my_wrapper <- function(fun_args = args_to_use) {
res_one <- do.call(my_sum, fun_args)
res_two <- do.call(my_exp, fun_args)
res_one + res_two
}
自然地,这个例子失败了,因为多余的参数被传递给了两个函数。
想要的结果
my_wrapper_two <- function(fun_args = args_to_use) {
res_one <- do.call(my_sum, fun_args[1:2]) # Only a, b
res_two <- do.call(my_exp, fun_args[3:4]) # Only c, d
res_one + res_two
}
my_wrapper_two()
# 84
寻求解决方案
我希望根据函数参数自动执行子集操作 [1:2]
和 [3:4]
。
备注
我正在考虑的一种方法是使用 names(formals(my_exp))
创建所需的参数列表,如:
my_wrapper_three <- function(fun_args = args_to_use) {
res_one <- do.call(my_sum, fun_args[names(formals(my_sum))])
res_two <- do.call(my_exp, fun_args[names(formals(my_exp))])
res_one + res_two
}
my_wrapper_three()
这看起来不太优雅,我想知道是否有更智能的解决方案?
更新
我想出的解决办法如下:
do_call_on_existing <- function(fun, args_list) {
fun_args <- names(formals(fun))
viable_args <- args_list[fun_args]
viable_args <- Filter(Negate(is.null), viable_args)
do.call(fun, viable_args)
}
Filter
/ Negate
位可防止函数失败,其中 my_sum
可能有额外的参数,导致参数列表返回 null
元素。所以代码可以工作:
my_sum <- function(a = 999, b = 999, c = 999) {a + b + c}
my_nms <- list(a = 1, b = 2)
do_call_on_existing(my_sum, my_nms)
试试这个(...
允许您将任意数量的参数传递给 my_sum
,但根据您的定义只使用 a
和 b
):
my_sum <- function(a, b, ...) {
a + b
}
my_exp <- function(c, d, ...) {
c^d
}
args_to_use <- as.list(1:4)
names(args_to_use) <- letters[1:4]
my_wrapper <- function(fun_args = args_to_use) {
res_one <- do.call(my_sum, fun_args)
res_two <- do.call(my_exp, fun_args)
res_one + res_two
}
背景
我对使用 do.call
通过一个列表将参数传递给两个函数很感兴趣。 do.call
解决方案应忽略未使用的参数。
例子
my_sum <- function(a, b) {
a + b
}
my_exp <- function(c, d) {
c^d
}
args_to_use <- as.list(1:4)
names(args_to_use) <- letters[1:4]
my_wrapper <- function(fun_args = args_to_use) {
res_one <- do.call(my_sum, fun_args)
res_two <- do.call(my_exp, fun_args)
res_one + res_two
}
自然地,这个例子失败了,因为多余的参数被传递给了两个函数。
想要的结果
my_wrapper_two <- function(fun_args = args_to_use) {
res_one <- do.call(my_sum, fun_args[1:2]) # Only a, b
res_two <- do.call(my_exp, fun_args[3:4]) # Only c, d
res_one + res_two
}
my_wrapper_two()
# 84
寻求解决方案
我希望根据函数参数自动执行子集操作 [1:2]
和 [3:4]
。
备注
我正在考虑的一种方法是使用 names(formals(my_exp))
创建所需的参数列表,如:
my_wrapper_three <- function(fun_args = args_to_use) {
res_one <- do.call(my_sum, fun_args[names(formals(my_sum))])
res_two <- do.call(my_exp, fun_args[names(formals(my_exp))])
res_one + res_two
}
my_wrapper_three()
这看起来不太优雅,我想知道是否有更智能的解决方案?
更新
我想出的解决办法如下:
do_call_on_existing <- function(fun, args_list) {
fun_args <- names(formals(fun))
viable_args <- args_list[fun_args]
viable_args <- Filter(Negate(is.null), viable_args)
do.call(fun, viable_args)
}
Filter
/ Negate
位可防止函数失败,其中 my_sum
可能有额外的参数,导致参数列表返回 null
元素。所以代码可以工作:
my_sum <- function(a = 999, b = 999, c = 999) {a + b + c}
my_nms <- list(a = 1, b = 2)
do_call_on_existing(my_sum, my_nms)
试试这个(...
允许您将任意数量的参数传递给 my_sum
,但根据您的定义只使用 a
和 b
):
my_sum <- function(a, b, ...) {
a + b
}
my_exp <- function(c, d, ...) {
c^d
}
args_to_use <- as.list(1:4)
names(args_to_use) <- letters[1:4]
my_wrapper <- function(fun_args = args_to_use) {
res_one <- do.call(my_sum, fun_args)
res_two <- do.call(my_exp, fun_args)
res_one + res_two
}