如果非空值提供给可选参数,我有一个函数可以执行额外的操作。如果未提供参数,则该函数不会执行任何额外操作。
使用NA
或NULL
会更好吗?两者有什么好处?
例如,如果我使用NA
,那么我可以使用函数体中的is.na(as.list(environment()))
来快速检查哪些参数未提供,这与is.null
无效。< / p>
以下是我想使用NA
我正在尝试构建一个到Geckoboard bar chart API的R连接器。它有许多可选参数。如果我执行以下操作,则可以非常轻松地使用包jsonlite
来提供可选参数。
get_barchart_json <- function(data, x_axis = list(labels = NA, type = NA), y_axis = list(format = NULL, unit = NULL)){
payload <- "{"
textappend(payload) <- '"series": [{"data":['
textappend(payload) <- paste0(data, collapse = ",")
textappend(payload) <- ']}]'
if(any(!is.na(x_axis))){
textappend(payload) <- ","
textappend(payload) <- jsonlite::toJSON(x_axis, auto_unbox = TRUE)
}
if(any(!is.na(y_axis))){
textappend(payload) <- ","
textappend(payload) <- jsonlite::toJSON(y_axis, auto_unbox = TRUE)
}
# finish construction
textappend(payload) <- '}'
return(payload)
}
返回,例如:
cat(get_barchart_json(data = c(1,2,3,4), x_axis = list(labels = c("a", "b", "c", "d"), format = "text"), y_axis = list(format = 'decimal')))
注意:textappend
是:
`textappend<-` <- function(payload, value){
payload <- paste0(payload, value)
payload
}
答案 0 :(得分:5)
NA表示数据集中缺少的数据值。它也会在NULL不会传播的地方传播,因为它可以是类型强制的。对于/ optional / value,请使用NULL。
我觉得它是一种允许缺少参数值的反模式 - 很难知道你遗漏了哪些值。对于NULL,第三个参数始终是第三个参数,等等......
答案 1 :(得分:4)
您实际上有3个选项:NA
,NULL
或无默认值。在大多数情况下,NULL
是最佳选择。
function(x, optional_arg = NULL)
{
if(is.null(optional_arg))
{
# do something
}
# rest of body code
}
如果您希望用户能够将NULL
作为合法值传递给optional_arg
,则此功能无效。在这种情况下,请使用
function(x, optional_arg)
{
if(missing(optional_arg))
{
# do something
}
# rest of body code
}
默认值NA
仅对可选arg应采用三个值之一的情况有用,将它存储为逻辑值而不是字符串更有意义。
function(x, optional_arg = NA)
{
if(is.na(optional_arg))
{
# do something
} else if(optional_arg)
{
# do something else
} else # case of optional_arg == FALSE
{
# do a third thing
}
# rest of body code
}
答案 2 :(得分:-1)
正如Hansi在评论中提到的那样,依赖于缺失对于交互式使用来说很好,但是对于使用嵌套函数进行编程使用会很烦人,这些函数将参数传递给向下。请考虑以下最低限度示例。
假设我们有一个函数在缺少arg2
时执行某些特殊操作。我们使用标准missing
方法进行检查。
> func1 = function(arg1, arg2) {
if (missing(arg2)) print("no arg2")
print(arg1)
}
> func1("abc")
[1] "no arg2"
[1] "abc"
这很好用。但是,如果我们从另一个传递参数的函数调用它并具有默认值?
> func2 = function(arg1, arg2 = "def") {
func1(arg1 = arg1, arg2 = arg2)
}
> func2("abc")
[1] "abc"
> func2("abc", arg2 = )
[1] "abc"
> func2("abc", arg2 = NULL)
[1] "abc"
> func2("abc", arg2 = NA)
[1] "abc"
我们似乎无法在arg2
丢失时触发特殊功能,因为从另一个从未丢失过的函数中设置arg2
并不容易论点。 Maybe not possible