在R语言中,NULL和character(0)有什么区别?

48

NULL和character(0) | integer(0)等之间有什么区别?

> identical(NULL, character(0))
[1] FALSE

> is.null(integer(0))
[1] FALSE

> str(character(0))
 chr(0) 

> str(NULL)
 NULL

一般情况下,似乎可以将NULL作为参数传递到函数中,并且通常会返回空向量,如character(0)integer(0)等。

为什么会这样呢?思考一下,是否有一个测试零的函数,类似于is.integer0


class(NULL); class(character(0)) - isomorphismes
3个回答

40

R 语言定义中对 NULL 的解释如下:

有一个特殊的对象叫做 NULL。每当需要指示或指定对象不存在时,就会使用它。它不应与长度为零的向量或列表混淆。NULL 对象没有类型和可修改的属性。在 R 中只有一个 NULL 对象,所有实例都指向它。要测试是否为 NULL,请使用 is.null。您无法在 NULL 上设置属性。

因此,按照定义,NULL 与零长度向量非常不同。零长度向量绝对不是不存在的。 NULL 实际上是用于表示缺失或未设置的万能符号,但不是缺失状态,这是 NA 的作用。有一种例外情况,即长度为零的 pairlist,正如 @Owen 所提到的那样。语言定义如下:

长度为零的 pairlist 是 NULL,这与 Lisp 中的期望相同,但与长度为零的 list 不同。

这里强调了这种情况的例外。

要测试零长度向量,请使用类似 if(length(foo) == 0L) 的语句。如果您想要特定类型的零长度向量,请与类检查(is.character(foo))结合使用。


2
请访问 https://dev59.com/6Gw05IYBdhLWcg3wiyfg,可以看到一个有趣的相似之处。 - Owen
@Owen 你说得对。我忽略了pairlists根本不是向量,即使它们具有非零长度。为避免任何额外的混淆,我已经删除了我的评论。 - goodside

11
其他人已经给出了正确的答案,但我想添加一些有趣的点。
首先,文档中说NULL“每当需要指示或指定对象不存在时使用”,这不完全是真实情况。实际上,在R中还有另外两个“无数据”值(不包括NA,它不是完整的值)。
其中一个是“missing”,用于丢失的参数:

alist(x=)$x

> identical(NULL, alist(x=)$x)
[1] FALSE
> y = alist(x=)$x
> y
Error: argument "y" is missing, with no default

还有一种叫做"unbound"的东西,据我所知无法直接访问,但可以使用C进行访问:

SEXP getUnbound(void) {
    return R_UnboundValue;
}

> x = .Call("getUnbound")
> x
Error: object 'x' not found

1
也许他们的意思是,NULL“被最终用户用于指示或指定对象不存在”,而在某些情况下,R在内部使用其他东西。 - joran

10

以下是部分答案,首先引用 R 语言定义指南:

有一个特殊的对象叫做 NULL。每当需要指示或说明对象不存在时就会使用它。它不应该被与长度为零的向量或列表混淆。NULL 对象没有类型和可修改的属性。R 中只有一个 NULL 对象,所有实例都指向它。使用 is.null 进行 NULL 测试。您无法在 NULL 上设置属性。

我理解这意味着长度为零的向量可以具有属性,而NULL则不行:

> x <- character(0)
> y <- NULL
> attr(x,"name") <- "nm"
> attr(y,"name") <- "nm"
Error in attr(y, "name") <- "nm" : attempt to set an attribute on NULL

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接