如何在没有任何一个为真的情况下同时使所有都为真?

4
a <- character()
b <- "SO is great"

any(a == b) 
#> [1] FALSE

all(a == b)
#> [1] TRUE

手册将“any”描述为: 给定一组逻辑向量,至少有一个值为真吗? 因此,在比较a == b中,即使没有一个值为TRUE,‘any’如何返回FALSE而‘all’返回TRUE呢? ‘all’被描述为给定一组逻辑向量,所有的值都是true吗? 简而言之:所有值都是TRUE,同时也没有一个值是TRUE? 我不是专家,但这看起来很奇怪。
问题:
  1. 是否有合理的解释还是只是R的一些怪癖?

  2. 有什么方法可以解决这个问题?

reprex package (v0.3.0)于2021-01-08创建


2
这是因为 a == b 在此处为空(因为 a 为空)。 - Stéphane Laurent
请查看 https://grokbase.com/t/r/r-help/044fjep5rq/r-all-logical-0-and-any-logical-0/oldest。 - lumartor
1
你引用手册中的完整句子是:“如果‘x’中至少有一个值为‘TRUE’,则返回的值为‘TRUE’;如果‘x’中所有值都为‘FALSE’(包括没有值),则返回‘FALSE’”(强调添加)。 - Ben Bolker
4个回答

3

关于第二个问题,我知道identical。在我能想到的所有情况下它都表现良好。

a <- "a"
b <- "b"
identical(a, b) # FALSE >> works
#> [1] FALSE

a <- character(0)
identical(a, b) # FALSE >> works
#> [1] FALSE

a <- NA
identical(a, b) # FALSE >> works
#> [1] FALSE

a <- NULL
identical(a, b) # FALSE >> works
#> [1] FALSE

a <- b
identical(a, b) # TRUE >> works
#> [1] TRUE

identical 看起来是一个不错的解决方法,尽管对于像我这样的兼职开发者来说,它仍然感觉像是一种变通办法。是否有更好的解决方案?为什么 R 会出现这种情况(请参见问题)?

此示例由 reprex 包 (v0.3.0) 在 2021-01-08 创建。


2
?all 中有一条注释:“all(logical(0)) 为真是一个有用的约定:它确保即使 x 的长度为零,all(all(x), all(y)) == all(x, y) 也成立。” a == b 的长度为零。 - markus

3
通常情况下,当比较 `a == b` 时,短向量的元素会根据需要进行循环。但在您的情况下,`a` 没有元素,因此没有循环,结果是一个空的逻辑向量。
`any(a == b)` 和 `all(a == b)` 的结果与逻辑量词“对于所有”和“存在”是一致的。如果您对一个空范围进行量化,“对于所有”给出逻辑连接(AND)的中性元素 `TRUE`,而“存在”则给出逻辑析取(OR)的中性元素 `FALSE`。
至于如何避免这种情况,请检查向量是否具有相同的大小,因为比较不同长度的向量很少有意义。

1

关于问题1) 我不确定是否正确,但是以下是我的想法:

在R中,all()any()的补集。为了保持一致性,all(logical(0))为真。所以,在你的情况下,你捕捉到了这个独特的情况。

在数学上,这类似于一个集合既是开放的又是闭合的。我不是计算机科学家,所以我无法解释为什么从很久以前的灰发老者中的一个要在R或S中实现这个。

关于问题2) 我认为其他回答已经回答得很好了。


1
在数学中,关于空集合元素的任何属性都是成立的,因为空集合中没有元素,所以你找不到一个使该属性不成立的元素。这与开集和闭集无关。 - Stéphane Laurent
是的,你说得对。我之前认为这两个概念是类似的,因为它们都依赖于理解其定义中的特定方面。 - BSCowboy

0

shiny包 提供的另一种解决方案是使用isTruthy()函数。 该包引入了真值和假值的概念,“通常表示当将一个值强制转换为base::logical()类型时,它是TRUE 还是 FALSE” (详见文档)。

require(shiny, quietly = TRUE)

a <- "a"
b <- "b"
isTruthy(a == b) # FALSE >> works
#> [1] FALSE

a <- character(0)
isTruthy(a == b) # FALSE >> works
#> [1] FALSE

a <- NA
isTruthy(a == b) # FALSE >> works
#> [1] FALSE

a <- NULL
isTruthy(a == b) # FALSE >> works
#> [1] FALSE

a <- b
isTruthy(a == b) # TRUE >> works
#> [1] TRUE

其中一个优点是您可以使用其他运算符,例如%in%match()

R中的情况是,当函数失败时,您永远不知道它会返回什么。一些函数返回NA,其他函数返回NULL,还有一些向量长度为0。isTruthy()使处理多样性变得更容易。

不幸的是,如果没有编写闪亮的应用程序,加载该软件包几乎没有意义,因为除了isTruthy之外,闪亮只添加了大量不需要的Web应用程序功能。

reprex package(v0.3.0)于2021-01-10创建


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