将参数传递给 R 中的调用函数时出现问题
Problem passing arguments to called functions in R
上下文: 我正在尝试使用调用其他函数 (callees).每个被调用函数都使用一组参数,这些参数可以因函数而异。
问题: 看来我必须在调用函数中使用参数才能将它们传递给被调用函数(参见下面示例中的 fun_d
).
问题:如何使用省略号来避免在调用函数中使用显式参数?
Using ellipsis in nested functions and 好像没有回答这个(或者我没理解正确)
代表:
# fun_a and fun_b have the same set of argument but do not do the same things with them
fun_a <- function(x, y, ...){x+y}
fun_b <- function(x, y, ...){x-y}
# I would like to use fun_a and fun_b in another function (fun_c) AND, have the possibility to
# give different values for each argument of fun_a and fun_b (ex: y1 and y2)
# I thought I could use the ellipsis like in fun_c:
fun_c <- function(...){
fa <- fun_a(x = x, y = y1)
fb <- fun_b(x = x, y = y2)
paste(fa, fb)
}
# fun_d works but I you like to understand why func_c does not
fun_d <- function(x, y1, y2, ...){
fa <- fun_a(x = x, y = y1)
fb <- fun_b(x = x, y = y2)
paste(fa, fb)
}
mapply(FUN = fun_c, x = c(1, 2, 3), y1 = c(1, 2, 3), y2 = c(0, 0, 0)) # not working, it says "x" is missing (and I suppose "y" too)
#> Error in fun_a(x = x, y = y1): object 'x' not found
mapply(FUN = fun_d, x = c(1, 2, 3), y1 = c(1, 2, 3), y2 = c(0, 0, 0)) # working
#> [1] "2 1" "4 2" "6 3"
由 reprex package (v2.0.0)
于 2021-06-23 创建
根据我的经验,通常可以通过将参数拉入命名空间来解决这个问题(未经测试):
fun_c <- function(...){
with(list(...), {
fa <- fun_a(x = x, y = y1)
fb <- fun_b(x = x, y = y2)
paste(fa, fb)
})
}
...
允许函数的调用者将任意参数传递给函数。
但它不会在函数内部创建相应的参数变量。如果你想在函数中使用通过 ...
传递的参数,你有这些选择:
您可以按原样传递 ...
。例如:
print_two_vectors = function (x, y, ...) {
print(x, ...)
print(y, ...)
}
这可用于将任意参数传递给常规 print
函数:
print_two_vectors(pi, exp(1), digits = 2L)
[1] 3.1
[1] 2.7
这个应该是...
最常使用的。对于大多数其他用途,您应该改为接受常规参数。
您可以通过 ..1
、..2
等顺序访问它们。...elt(n)
为您提供 n第一个论点。要找出 传递了多少 个参数,您可以使用 ...length()
:
example = function (...) {
message('Got ', ...length(), ' arguments. The first two are: ', toString(c(..1, ..2)))
message('The last one is: ', toString(...elt(...length())))
}
输出结果如下:
example(1, 2, 3, 4)
Got 4 arguments. The first two are: 1, 2
The last one is: 4
您可以将它们解压缩到一个列表中。严格来说,这与 (1) 相同,即您只是将 ...
传递给 list
函数。这允许您通过名称 访问元素 ,因为列表可以命名为:
add_xy = function (...) {
args = list(...)
args$x + args$y
}
add_xy(x = 1, y = 2)
[1] 3
……好吧,那个例子有点没用。但是您可以使用相同的方法来解决您的问题。
您可以在未计算的上下文中访问 ...
的值。这是一个高级主题。它在 R 的“常规”使用中并不经常有用,但在 using non-standard evaluation for metaprogramming.
时它变得强大
add_xy2 = function (...) {
call = match.call()
eval.parent(call$x) + eval.parent(call$y)
}
add_xy2(x = 1, y = 2)
[1] 3
上下文: 我正在尝试使用调用其他函数 (callees).每个被调用函数都使用一组参数,这些参数可以因函数而异。
问题: 看来我必须在调用函数中使用参数才能将它们传递给被调用函数(参见下面示例中的 fun_d
).
问题:如何使用省略号来避免在调用函数中使用显式参数?
Using ellipsis in nested functions and
代表:
# fun_a and fun_b have the same set of argument but do not do the same things with them
fun_a <- function(x, y, ...){x+y}
fun_b <- function(x, y, ...){x-y}
# I would like to use fun_a and fun_b in another function (fun_c) AND, have the possibility to
# give different values for each argument of fun_a and fun_b (ex: y1 and y2)
# I thought I could use the ellipsis like in fun_c:
fun_c <- function(...){
fa <- fun_a(x = x, y = y1)
fb <- fun_b(x = x, y = y2)
paste(fa, fb)
}
# fun_d works but I you like to understand why func_c does not
fun_d <- function(x, y1, y2, ...){
fa <- fun_a(x = x, y = y1)
fb <- fun_b(x = x, y = y2)
paste(fa, fb)
}
mapply(FUN = fun_c, x = c(1, 2, 3), y1 = c(1, 2, 3), y2 = c(0, 0, 0)) # not working, it says "x" is missing (and I suppose "y" too)
#> Error in fun_a(x = x, y = y1): object 'x' not found
mapply(FUN = fun_d, x = c(1, 2, 3), y1 = c(1, 2, 3), y2 = c(0, 0, 0)) # working
#> [1] "2 1" "4 2" "6 3"
由 reprex package (v2.0.0)
于 2021-06-23 创建根据我的经验,通常可以通过将参数拉入命名空间来解决这个问题(未经测试):
fun_c <- function(...){
with(list(...), {
fa <- fun_a(x = x, y = y1)
fb <- fun_b(x = x, y = y2)
paste(fa, fb)
})
}
...
允许函数的调用者将任意参数传递给函数。
但它不会在函数内部创建相应的参数变量。如果你想在函数中使用通过 ...
传递的参数,你有这些选择:
您可以按原样传递
...
。例如:print_two_vectors = function (x, y, ...) { print(x, ...) print(y, ...) }
这可用于将任意参数传递给常规
print
函数:print_two_vectors(pi, exp(1), digits = 2L)
[1] 3.1 [1] 2.7
这个应该是
...
最常使用的。对于大多数其他用途,您应该改为接受常规参数。您可以通过
..1
、..2
等顺序访问它们。...elt(n)
为您提供 n第一个论点。要找出 传递了多少 个参数,您可以使用...length()
:example = function (...) { message('Got ', ...length(), ' arguments. The first two are: ', toString(c(..1, ..2))) message('The last one is: ', toString(...elt(...length()))) }
输出结果如下:
example(1, 2, 3, 4)
Got 4 arguments. The first two are: 1, 2 The last one is: 4
您可以将它们解压缩到一个列表中。严格来说,这与 (1) 相同,即您只是将
...
传递给list
函数。这允许您通过名称 访问元素 ,因为列表可以命名为:add_xy = function (...) { args = list(...) args$x + args$y }
add_xy(x = 1, y = 2)
[1] 3
……好吧,那个例子有点没用。但是您可以使用相同的方法来解决您的问题。
您可以在未计算的上下文中访问
时它变得强大...
的值。这是一个高级主题。它在 R 的“常规”使用中并不经常有用,但在 using non-standard evaluation for metaprogramming.add_xy2 = function (...) { call = match.call() eval.parent(call$x) + eval.parent(call$y) }
add_xy2(x = 1, y = 2)
[1] 3