我对dot-dot-dot参数的范围有疑问.考虑以下函数`foo =
foo <- function(x, ...){
require(classInt);
intvl = classIntervals(x, ...);
return(intvl);
}
Run Code Online (Sandbox Code Playgroud)
该功能适用于以下调用
x = runif(100, 0, 100);
y1 = foo(x, n = 5, style = 'quantile');
y2 = foo(x, style = 'equal');
Run Code Online (Sandbox Code Playgroud)
但是当我尝试使用style ='fixed'参数时,我需要一个fixedBreaks参数
y3 = foo(x, style = 'fixed', fixedBreaks = seq(0, 100, 20))
Run Code Online (Sandbox Code Playgroud)
eval中的错误(expr,envir,enclos):...列表不包含2个元素
请注意,以下工作完美
y5 = classIntervals(x, style = 'fixed', fixedBreaks = seq(0, 100, 20))
Run Code Online (Sandbox Code Playgroud)
我怀疑这与范围规则有关,但一直无法指责它.任何有关这方面的帮助将非常感谢.
编辑.我拼凑了一个更简单的黑客,使它工作.我认为这是一个match.call问题,因为style ='pretty'存在同样的问题.快速查看代码显示这些是match.calls的两种样式,所以很可能这是错误的来源.无论如何,这是我提出的黑客攻击
foo2 <- function(x, ...){
require(classInt);
y = list(...); y$var = x;
intvl = do.call('classIntervals', y);
}
y6 = foo2(x, style = 'fixed', fixedBreaks = seq(0, 100, 20))
Run Code Online (Sandbox Code Playgroud)
我认为Richie对我的问题的回答揭示了我早期代码无法工作的原因.但是,我仍然不明白为什么这样做.
在foo函数内部,省略号确实包含 2 个元素。调用此修改即可看到这一点。
foo <- function(x, ...){
require(classInt);
print(list(...))
intvl = classIntervals(x, ...);
return(intvl);
}
Run Code Online (Sandbox Code Playgroud)
一旦classIntervals被调用,省略号就会改变,因为参数的匹配方式不同。这是该函数的签名
classIntervals(var, n, style = "quantile", rtimes = 3, ...,
intervalClosure = "left", dataPrecision = NULL)
Run Code Online (Sandbox Code Playgroud)
在失败的调用中,您有三个参数
foo(x, style = 'fixed', fixedBreaks = seq(0, 100, 20))
Run Code Online (Sandbox Code Playgroud)
x通过位置匹配来匹配var(即,因为它在每种情况下都位于签名中的第一个位置)。
style通过名称匹配匹配到style, (因为它们具有相同的名称,duh)。
fixedBreaks无法通过位置或名称匹配,因此它最终会出现在点中。
因此,省略号包含 1 个参数,并且错误“The ... list does not contains 2 elements”是正确的(虽然相当愚蠢)。
编辑:建议修复classIntervals. 如果您正在联系作者,建议替换第 42-43 行
mc <- match.call(expand.dots = FALSE)
fixedBreaks <- sort(eval(mc$...$fixedBreaks))
Run Code Online (Sandbox Code Playgroud)
和
fixedBreaks <- list(...)$fixedBreaks
Run Code Online (Sandbox Code Playgroud)
这就是(我认为)他们的意思,并且似乎解决了愚蠢的错误消息。