使用下面的函数foo()
作为一个简单的例子,如果可能的话,我想将...
中给出的值分配给两个不同的函数。
foo <- function(x, y, ...) {
list(sum = sum(x, ...), grep = grep("abc", y, ...))
}
在下面的例子中,我想把na.rm
传递给sum()
,把value
传递给grep()
,但是grep()
中有一个未使用的参数,我得到了一个错误。
X <- c(1:5, NA, 6:10)
Y <- "xyzabcxyz"
foo(X, Y, na.rm = TRUE, value = TRUE)
# Error in grep("abc", y, ...) : unused argument (na.rm = TRUE)
看起来参数是先发送到grep()
的,对吗?我认为R会先看到并计算sum()
,然后返回一个错误。
此外,在尝试拆分...
中的参数时,我遇到了麻烦。sum()
的形式参数是NULL
,因为它是.Primitive
,因此不能使用
names(formals(sum)) %in% names(list(...))
我也不想假设剩下的论点
names(formals(grep)) %in% names(list(...))
将自动传递到sum()
。
如何安全高效地将...
参数分发给多个函数,从而避免不必要的求值?
从长远来看,我希望能够将此应用于具有一长串...
参数的函数,类似于download.file()
和scan()
。
5条答案
按热度按时间prdp8dxp1#
单独的列表如果你真的想给不同的函数传递不同的参数集,那么指定单独的列表可能更简洁:
**混合列表/...**另一种方法是我们可以对其中一个使用...,然后将另一个指定为列表,特别是在其中一个经常使用而另一个不经常使用的情况下。经常使用的一个通过...传递,不经常使用的通过列表传递。例如:
下面是R本身的几个混合方法的例子:
i)
mapply
函数采用使用...
和MoreArgs
列表的方法:ii)
nls
也采用使用...
和control
列表两者的这种方法:eyh26e7m2#
1.为什么
grep
在sum
之前出错?可以看到
sum
在参数方面更加灵活:它不会失败,因为它不关心其他命名参数,所以
value = TRUE
简化为TRUE
,其总和为1。1.如何将
...
拆分为不同的函数?一种方法(很容易出错)是查找目标函数的参数,例如:
每当
args
(例如S3对象)没有正确报告函数 * 使用 * 的参数时,这很容易出错。在这种情况下,您可以替换为适当的S3函数,因此,我没有一个通用的解决方案(尽管我不知道它是否存在)。
uurity8g3#
如果另一个函数包含了传递给
...
的所有命名参数,或者它本身有一个...
参数,则只能将...
参数传递给另一个函数。因此对于sum
,这没有问题(args(sum)
返回function (..., na.rm = FALSE)
)。另一方面,grep
既没有na.rm
也没有...
作为参数。这不包括
...
,也不包括命名参数na.rm
。一个简单的解决方案是定义你自己的函数mygrep
,如下所示:然后它似乎起作用了:
zd287kbt4#
TL;DR
考虑使用在
plot.default
和其他地方实现的“技巧”。它是经过尝试和测试的。我有点震惊,
plot.default
使用的“技巧”还没有出现在这里。(也许它在其他地方提到过?)回想一下,
plot.default
必须处理内部plot.xy
(用于点和线)的可选参数 * 以及plot.window
、box
、axis
和title
的可选参数 *,这些都是通过一个...
参数处理的。重要的是,当我们将
lwd = 6
传递给plot.default
来加宽绘图区域中的线时,plot.default
必须确保box
和axis
看不到这个参数,这两个参数使用lwd
来设置绘图区域边界和轴线的宽度。plot.default
的此功能是使用子函数plot.window
、box
、axis
和title
的“本地”版本实现的。本地版本只是 Package 器,旨在过滤掉...
中不允许子函数查看的参数(在这种情况下为col
、bg
、pch
、cex
、lty
和lwd
)。让我们以
localTitle
为例:plot.default
在调用时将...
中的所有参数传递给localTitle
但是
title
只会看到那些没有命名为col
、bg
、pch
、cex
、lty
或lwd
的自变量,因为这些自变量被包括作为localTitle
的形式自变量。值得注意的是,这种处理
...
的方法具有最小的开销,因为它充分利用了惰性求值。...
中的表达式在被子函数使用之前不会被求值。ct2axkht5#
这个答案并不直接回答最初的问题,但可能对其他在 * 自己的 * 函数(而不是 * 现有的 * 函数,如
sum
和grep
)上遇到类似问题的人有所帮助。@shadow的回答包含了一个见解,指出了在这种情况下一个非常简单的解决方案:只要确保嵌套函数有
...
作为参数,就不会出现unused argument
错误。例如:
如果我们调用
f(x = 2, a = 3, b = 4)
,我们会得到一个错误:Error in nested1(x, ...) : unused argument (b = 4)
.但是,只需将
...
添加到nested1
和nested2
的形式中,然后再次运行:现在,
f(x = 2, a = 3, b = 4)
将产生所需的结果:5
.问题解决了。