Should I use NULL or NA as default values ​​for optional function parameters

I have a function that does extra things if a non-empty value is passed to what would otherwise be an optional parameter. If no argument is specified, the function does nothing more.

Is it better to use NAor NULL? What are the benefits?

For example, if I use NA, then I can quickly check which arguments were not provided using: is.na(as.list(environment()))in the body of a function that does not work with is.null.

Here is an example of why I want to use NA

I am trying to build an R-connector for the Geckoboard histogram API . It has many optional arguments. If I do the following, it is very simple to use the package jsonliteto provide optional arguments.

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)

}

which returns for example:

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')))

NB textappend::

`textappend<-` <- function(payload, value){
 payload <- paste0(payload, value)    
 payload
}
+4
source share
3 answers

NA - for data values ​​that are not in the data sets. It will also be distributed in places where NULL will not be, since it can be forced. For / optional /, use NULL.

, -, - , . NULL ..

. NA NULL.

+5

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

, , , , . .

, , - , 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"

We cannot run a special function if it is arg2missing, because it is not easy to set arg2to remove from another function that has never had an missing argument. Perhaps not possible .

Also discussed on this blogpost .

0
source

All Articles