何时使用missing和NULL值在R中传递未定义的函数参数,为什么?

时间:2014-02-25 19:21:26

标签: r function null parameter-passing

到目前为止,在编写R函数时,我已经传递了未定义的参数 作为NULL值,然后测试它们是否为NULL,即

f1 <- function (x = NULL) {
   if(is.null(x))
      ...
}

但是我最近发现了将未定义的参数传递为缺失的可能性。

f2 <- function (x) {
   if(missing(x))
      ...
}

R文档指出

  

目前丢失的只能在直接身体中使用   定义参数的函数,而不是在函数体中   嵌套函数或本地调用。这可能在将来发生变化。

显然,这是使用缺失来确定未定义值的一个缺点是否有其他人或意识到?或者以更有用的形式表达问题“你何时使用缺失与NULL值来传递R中未定义的函数参数?为什么?”

3 个答案:

答案 0 :(得分:6)

NULL只是您可以分配给变量的另一个值。它与您在函数声明中指定的任何其他默认值没有什么不同。

另一方面,

missing检查用户是否提供了该参数,你可以在之前进行默认分配 - 这要归功于R的惰性评估仅在使用该变量时发生。

使用此功能可以实现的几个示例是:没有默认值的参数,您仍然可以省略 - 例如file中的textread.table,或带有默认值的参数,您只能在其中指定一个 - 例如n中的nmaxscan

通过浏览R代码,您会发现许多其他用例。

答案 1 :(得分:5)

missing(x)似乎比使用等于x的{​​{1}}默认arg快一点。

NULL

请注意,> require('microbenchmark') > f1 <- function(x=NULL) is.null(x) > f2 <- function(x) missing(x) > microbenchmark(f1(1), f2(1)) Unit: nanoseconds expr min lq median uq max neval f1(1) 615 631 647.5 800.5 3024 100 f2(1) 497 511 567.0 755.5 7916 100 > microbenchmark(f1(), f2()) Unit: nanoseconds expr min lq median uq max neval f1() 589 619 627 745.5 3561 100 f2() 437 448 463 479.0 2869 100 案例f1如果您拨打电话x,仍然会报告为f1(),但其值可能会在f1内被读取。

第二种情况比第一种情况更为普遍。 missing()仅表示用户未传递任何值。 is.null()NULL默认arg)指出用户未传递任何内容或他/她通过NULL

顺便说一句,plot.default()chisq.test()使用NULL作为他们的第二个参数。另一方面,getS3method('t.test', 'default')使用NULL表示y参数,使用missing()表示mu(以便为许多使用方案做好准备)。

我认为某些R用户更喜欢f1类型的功能,尤其是在使用*apply系列时:

sapply(list(1, NULL, 2, NULL), f1)

f2案例中实现这一点并不是那么简单。

答案 2 :(得分:1)

我认为,missing的限制何时适用尚不清楚。如您所引用的文档所述,缺少只能在函数的直接正文中使用。不过,有一个简单的示例表明情况并非如此,并且在将参数传递给嵌套函数时,它可以按预期工作。

f1 = function(x, y, z){
  if(!missing(x))
    print(x)
  if(!missing(y))
    print(y)
}

f2 = function(x, y, z){
  if(!missing(z)) print(z)
  f1(x, y)
}
f1(y="2")
#> [1] "2"
f2(y="2", z="3")
#> [1] "3"
#> [1] "2"
f2(x="1", z="3")
#> [1] "3"
#> [1] "1"

我想看看一个例子,其中missing在嵌套函数中不起作用。

reprex package(v0.2.1)于2019-09-30创建