【问题标题】:R does not report error when an argument of a function is not provided but used for subsetting a vector当函数的参数未提供但用于子集向量时,R 不会报告错误
【发布时间】:2018-04-26 01:49:58
【问题描述】:

为什么在函数内部没有提供但需要b时没有报告错误?谢谢!

f2 <- function(a,b) {a[b]}; f2(a=rep(1, 2))

我明白这个函数没有错误:

f <- function(x) {
  10
}
f(stop("This is an error!"))

由于懒惰的评估 但是这个

f <- function(x) {
  force(x)
  10
}
f(stop("This is an error!"))

或者这个

f <- function(x) {
  x
  10
}
f(stop("This is an error!"))

会产生错误。因为在这两种情况下 x 在函数中使用。以上两个例子均来自http://adv-r.had.co.nz/Functions.html。既然 b 也在 f2 中使用,是否有必要在 f2 中加力?谢谢!

【问题讨论】:

  • 更简单的版本,同样的问题 - f2 &lt;- function(a,b) {a[b]}; f2(a=1)
  • 我猜这是我不完全理解的一些懒惰的评估怪癖,因为如果你debug(f2) 你可以看到b 是从函数环境中的ls() 返回的。一旦 ?force 与 'argument "b" is missing" 错误一起使用,f2 &lt;- function(a,b) {a[force(b)]}; f2(a=1:2) 也会失败。来源:stackoverflow.com/questions/29733257/…
  • 但我认为在上面的链接中,原来的函数 f 没有使用stackoverflow.com/questions/29733257/…

标签: r function arguments parameter-passing


【解决方案1】:

x[b] 如果缺少b,则返回(与)x。来自 R 源代码:

static SEXP VectorSubset(SEXP x, SEXP s, SEXP call)
{
    R_xlen_t stretch = 1;
    SEXP indx, result, attrib, nattrib;

    if (s == R_MissingArg) return duplicate(x);

https://github.com/wch/r-source/blob/ec2e89f38a208ab02449b706e13f278409eff16c/src/main/subset.c#L169

从文档中,“空”表示“丢失”,而不是NULL

空索引选择所有值:这最常用于替换所有条目但保留属性。

【讨论】:

    【解决方案2】:

    它与[ 函数有关,而不是惰性求值。如果您执行以下操作,您将收到错误消息:

    f3 <- function(a,b) {a+b}; f3(a = 1)
    

    请注意,由于 b 没有定义,R 将它解释为好像它不存在一样。尝试做:

    a <- c(1,1) 
    a[]
    

    似乎子集函数(`[`)实际上将...作为参数。即,为子集指定索引是可选的。

    【讨论】:

    • 再次比较一下执行此操作时会发生什么:f4 &lt;- function(a, ...) {a+...}; f4(1); f4(1,1); f4(1, c(1,1))。对于子集函数,索引是可选的 (...)。当您像上面那样调用f2 时,R 会在环境中搜索变量b,但由于它无法匹配任何内容,因此它只使用a 执行该功能。这在我的 f3 示例中不起作用,因为添加需要定义两个变量。
    • @DavidKlotz - 但b 确实存在于环境中。 debug(f2); f2(a=1) 然后exists("b") 返回TRUE。所以它存在但没有被评估,对吧?
    • 在函数调用中定义了,但还是不见了:f2 &lt;- function(a,b) {print(missing(a)); print(missing(b)); a[b]}; f2(a=rep(1, 2))
    • 除了关于... 的部分之外,这里的一切都是正确的。如果涉及...`[`(a, i = 1, foo = 1) 将起作用。
    • 最好的方法是明确检查缺失:f &lt;- function(a, b) if (missing(b)) stop('b is missing.') else a[b]
    猜你喜欢
    • 2021-05-26
    • 1970-01-01
    • 2020-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多