何时在R中使用缺失值与空值来传递未定义的函数参数,为什么?
到目前为止,在编写R函数时,我已经传递了未定义的参数 作为空值,然后测试它们是否为空何时在R中使用缺失值与空值来传递未定义的函数参数,为什么?,r,function,null,parameter-passing,R,Function,Null,Parameter Passing,到目前为止,在编写R函数时,我已经传递了未定义的参数 作为空值,然后测试它们是否为空 f1 <- function (x = NULL) { if(is.null(x)) ... } f1NULL只是可以分配给变量的另一个值。它与您在函数声明中指定的任何其他默认值没有什么不同 missing另一方面检查用户是否提供了该参数,您可以在默认赋值之前执行,这要归功于R的惰性求值,只有在使用该变量时才会发生 使用此功能可以实现的两个示例是:没有默认值但仍然可以忽略的参数-例如r
f1 <- function (x = NULL) {
if(is.null(x))
...
}
f1NULL
只是可以分配给变量的另一个值。它与您在函数声明中指定的任何其他默认值没有什么不同
missing
另一方面检查用户是否提供了该参数,您可以在默认赋值之前执行,这要归功于R的惰性求值,只有在使用该变量时才会发生
使用此功能可以实现的两个示例是:没有默认值但仍然可以忽略的参数-例如read.table
中的file
和text
,或者只有一个默认值的参数-例如n
和scan
中的nmax
通过浏览R代码,您会发现许多其他用例。missing(x)
似乎比使用默认参数将x
等于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
在f2
的情况下实现这一点并不那么简单。在我看来,不清楚对缺失的限制何时适用。正如您所引用的文档所述,missing只能在函数的直接主体中使用。不过,一个简单的例子表明,情况并非如此,当参数传递给嵌套函数时,它会按预期工作
f1=函数(x,y,z){
如果(!缺少(x))
打印(x)
如果(!缺失(y))
打印(y)
}
f2=函数(x,y,z){
如果(!缺少(z))打印(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
在嵌套函数中不起作用
由(v0.2.1)于2019-09-30创建,我想NULL
非常方便的一种情况是,函数中的一个参数可以忽略或在长度==0时进行操作。例如,在f1=function(x,y=NULL)c(x,y)
中,调用f1(3)
不会产生错误(如果NULL
不存在,则会产生错误),并且不需要额外检查。我没有意识到在f1
案例中,如果调用f1()
,则x
仍然报告为缺失。在一般情况下,设置默认值似乎是最有用的,而且它可以让用户明白他们不必提供值。在R 3.0.2中,text
似乎是scan
中唯一没有默认值的参数。你知道这是不是有什么特别的原因吗?这是一个很好的答案的萌芽,但你需要对此进行扩展:当你有多个参数指示不同的/冲突的模式或用例(例如,read.csv(file/text
)时,使用missing而不是null,并且你的默认活动必须在其中一个案例中进行选择(在?missing
)是2002年写的。看起来这在过去17年的某个时候确实发生了变化,但文档没有。或者可能引用的是嵌套函数,例如f2
> 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
sapply(list(1, NULL, 2, NULL), f1)