What is the difference between NULL and character(0) | integer(0) etc?
> identical(NULL, character(0)) [1] FALSE > is.null(integer(0)) [1] FALSE > str(character(0)) chr(0) > str(NULL) NULL
In general it seems you can pass NULL
as parameters into functions, and that an empty vector is generally returned as character(0)
, integer(0)
, etc.
Why is this the case? Come to think of it, is there a test for zero-ness, a la is.integer0
?
The R Language Definition has this on NULL
:
There is a special object called NULL. It is used whenever there is a need to indicate or specify that an object is absent. It should not be confused with a vector or list of zero length. The NULL object has no type and no modifiable properties. There is only one NULL object in R, to which all instances refer. To test for NULL use is.null. You cannot set attributes on NULL.
So by definition NULL
is very different to zero length vectors. A zero length vector very much isn't absent. NULL
is really a catch-all for something that is absent or not set, but not missing-ness, which is the job of NA
. There is an exception, the zero-length pairlist, as mentioned by @Owen. The Language Definition states:
A zero-length pairlist is NULL, as would be expected in Lisp but in contrast to a zero-length list.
which highlights the exception in this case.
To test for a zero-length vector use something like if(length(foo) == 0L)
for example. And combine that with a class check (is.character(foo)
) if you want a specific type of zero length vector.
The other guys have the right answers, but I want to add a few curiosities.
First, it's not quite true that NULL "is used whenever there is a need to indicate or specify that an object is absent" as it says in the doc. There are actually 2 other "no data" values in R (not counting NA, which is not a complete value).
There's "missing", which is used for missing arguments:
alist(x=)$x
> identical(NULL, alist(x=)$x) [1] FALSE > y = alist(x=)$x > y Error: argument "y" is missing, with no default
Then there's "unbound", which you can't (AFAIK) access directly, but using C:
SEXP getUnbound(void) { return R_UnboundValue; } > x = .Call("getUnbound") > x Error: object 'x' not found
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With