if语句中的logical(0)

25
这一行:

which(!is.na(c(NA,NA,NA))) == 0

生成 logical(0)

尽管这一行

if(which(!is.na(c(NA,NA,NA))) == 0){print('TRUE')}
生成:
Error in if (which(!is.na(c(NA, NA, NA))) == 0) { : 
  argument is of length zero

为什么会出现错误?什么是logical(0)


6
长度为0的逻辑(布尔)向量。由于长度为零,它没有真假值,所以if条件不成立。 - joran
3
你可以像这样做:if(any(!is.na(c(NA,NA,NA))) == 0){print('TRUE')} - patL
2
如果您将 which 替换为 sum,则会得到预期的行为,即 if(sum(!is.na(c(NA,NA,NA))) == 0){print('TRUE')} - Sotos
4个回答

29

logical(0)是一个长度为0的基础类型为逻辑型的向量。你得到这个结果是因为你在询问这个向量中哪些元素等于0:

> !is.na(c(NA, NA, NA))
[1] FALSE FALSE FALSE
> which(!is.na(c(NA, NA, NA))) == 0
logical(0)
在下一行中,你询问零长度向量 logical(0) 是否等于0,实际上并不等。你遇到错误是因为无法将0长度的向量与标量进行比较。
相反,你可以检查第一个向量的长度是否为0:
if(length(which(!is.na(c(NA,NA,NA)))) == 0){print('TRUE')}

“vector of class logical” 应该是 “vector of mode logical”,我认为。 - David Tonhofer
@DavidTonhofer 你为什么认为应该使用 mode 而不是 class? - Eugene Brown
2
因为“class”是面向对象宇宙的术语,但“mode”实际上是“基本类型”的R术语(旧)。“基本类型”更好。来自:Advanced R从技术上讲,基本对象和OO对象之间的区别在于OO对象具有“class”属性_,但也有:_您可能听说过mode()和storage.mode()。不要使用这些函数:它们仅存在以提供与S兼容的类型名称。 - David Tonhofer
1
好的,感谢您的建议。我已经将“class”更改为“基本类型”,因为它似乎是三个选项中最好的选择。 - Eugene Brown

8

使用which检查逻辑向量是否全部为false是一个不好的想法。which会给你一个由TRUE值的索引构成的向量。如果没有,则该向量长度为0。更好的方法是利用any

> any(!is.na(c(NA,NA,NA)))
FALSE

7
首先,logical(0) 表示您有一个应该包含布尔值的向量,但是这个向量长度为零。
在您的第一种方法中,您执行
!is.na(c(NA, NA, NA))
# FALSE, FALSE, FALSE

使用which()函数对这个向量进行操作,将产生一个空的整数向量(integer(0))。测试一个空集合是否等于零,会导致一个空的布尔向量。
在您的第二种方法中,您尝试查看向量which(!is.na(c(NA,NA,NA))) == 0是否为TRUEFALSE。然而,它既不是TRUE也不是FALSE,因为它是空的。if语句需要一个TRUEFALSE。这就是为什么它给出了一个错误argument is of length zero

4

只需使用length(),如下所示:

foo <- logical(0)

if(length(foo) == 0) { } # TRUE
if(length(foo) != 0) { } # FALSE

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