到目前为止,在编写R函数时,我已经传递了未定义的参数 作为NULL值,然后测试它们是否为NULL,即
f1 <- function (x = NULL) {
if(is.null(x))
...
}
但是我最近发现了将未定义的参数传递为缺失的可能性。
f2 <- function (x) {
if(missing(x))
...
}
R文档指出
目前丢失的只能在直接身体中使用 定义参数的函数,而不是在函数体中 嵌套函数或本地调用。这可能在将来发生变化。
显然,这是使用缺失来确定未定义值的一个缺点是否有其他人或意识到?或者以更有用的形式表达问题“你何时使用缺失与NULL值来传递R中未定义的函数参数?为什么?”
答案 0 :(得分:6)
NULL
只是您可以分配给变量的另一个值。它与您在函数声明中指定的任何其他默认值没有什么不同。
missing
检查用户是否提供了该参数,你可以在之前进行默认分配 - 这要归功于R的惰性评估仅在使用该变量时发生。
使用此功能可以实现的几个示例是:没有默认值的参数,您仍然可以省略 - 例如file
中的text
和read.table
,或带有默认值的参数,您只能在其中指定一个 - 例如n
中的nmax
和scan
。
通过浏览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创建