我应该使用NULL或NA作为可选功能参数的默认值

时间:2015-04-14 04:56:29

标签: r function

如果非空值提供给可选参数,我有一个函数可以执行额外的操作。如果未提供参数,则该函数不会执行任何额外操作。

使用NANULL会更好吗?两者有什么好处?

例如,如果我使用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
}

3 个答案:

答案 0 :(得分:5)

NA表示数据集中缺少的数据值。它也会在NULL不会传播的地方传播,因为它可以是类型强制的。对于/ optional / value,请使用NULL。

我觉得它是一种允许缺少参数值的反模式 - 很难知道你遗漏了哪些值。对于NULL,第三个参数始终是第三个参数,等等......

NA vs. NULL

答案 1 :(得分:4)

您实际上有3个选项:NANULL或无默认值。在大多数情况下,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

Also discussed on this blogpost