布尔运算符 && 和 & 之间的区别 ||和 |在 R 中



根据R语言的定义,&&&(相应的|||)之间的区别在于前者是矢量化的,而后者不是。

根据帮助文本,我读到的区别类似于"And"one_answers"AndAlso"之间的区别(对应的是"Or"和《OrElse》)。。。含义:如果不是所有的评估都必须是(即,如果A是真的,A、B或C总是真的,所以如果A是真实的,就停止评估)

有人能照亮这里吗?此外,R中是否存在AndAlso和OrElse?

较短的被矢量化,这意味着它们可以返回一个矢量,如下所示:

((-2:2) >= 0) & ((-2:2) <= 0)
# [1] FALSE FALSE  TRUE FALSE FALSE

较长的形式不是,因此(从4.3.0开始)必须提供长度为1的输入。(万岁!需要的检查更少,见下文。)

直到R 4.3.0,给出&amp;长度>1没有抛出错误,而是从左到右评估,只检查每个向量的第一个元素,因此上面给出:

((-2:2) >= 0) && ((-2:2) <= 0)
# [1] FALSE

正如帮助页面所说;适用于编程控制流,并且在if子句中通常是首选"

因此,只有当你确定向量的长度为1时,你才想使用长形式,从4.3.0开始,R强制执行这一点。

如果你使用的是以前的版本,你应该绝对确定你的向量只有长度1,比如在它们是只返回长度1布尔值的函数的情况下。如果向量的长度可能>1.因此,如果您不能完全确定,您应该先检查,或者使用缩写形式,然后使用allany将其缩短为长度1,以便在控制流语句中使用,如if

函数allany经常用于矢量化比较的结果,以分别查看所有或任何比较是否为真。这些函数的结果长度肯定是1,因此它们适合在if子句中使用,而矢量化比较的结果则不适合。(尽管这些结果适用于ifelse。)

最后一个区别是:&&||只评估他们需要的项(这通常被称为短路)。例如,这里有一个使用未定义值a的比较;如果它没有短路,就像&|没有短路一样,它将给出一个错误。

a
# Error: object 'a' not found
TRUE || a
# [1] TRUE
FALSE && a
# [1] FALSE
TRUE | a
# Error: object 'a' not found
FALSE & a
# Error: object 'a' not found

最后,参见R Inferno中的第8.2.17节,标题为";和and and";。

关于";"短路";具有潜在的误导性,但有一定的真实性(见下文)。在R/S语言中,&&||只计算第一个自变量中的第一个元素。向量或列表中的所有其他元素都将被忽略,而不管第一个值是多少。这些操作符被设计为与if (cond) {} else{}构造一起工作,并指导程序控制,而不是构造新的向量。。&|算子被设计用于处理向量,因此它们将被应用于"向量";"并行";,可以说,沿着最长争论的长度。在进行比较之前,需要对两个矢量进行评估。如果向量的长度不相同,则执行较短参数的循环。

当对&&||的自变量进行评估时;"短路";因为如果从左到右连续的任何值都是决定性的,那么评估就会停止,并返回最终值。

> if( print(1) ) {print(2)} else {print(3)}
[1] 1
[1] 2
> if(FALSE && print(1) ) {print(2)} else {print(3)} # `print(1)` not evaluated
[1] 3
> if(TRUE && print(1) ) {print(2)} else {print(3)}
[1] 1
[1] 2
> if(TRUE && !print(1) ) {print(2)} else {print(3)}
[1] 1
[1] 3
> if(FALSE && !print(1) ) {print(2)} else {print(3)}
[1] 3

只有当参数需要很长时间才能评估时,短路的优势才会显现出来。当参数是处理较大对象或具有更复杂数学运算的函数时,通常会发生这种情况。

更新:最新版本的news(“R”)表示,向&&||提供长度大于1的矢量是不推荐的,并发出警告,RCore的目的是使其成为R的后续版本中的错误。

&&||是所谓的"短路"。这意味着,如果第一个操作数足以确定表达式的值,则它们不会计算第二个操作数。

例如,如果&&的第一个操作数为false,那么计算第二个操作数就没有意义,因为它不能更改表达式的值(false && truefalse && false都为false)。当第一个操作数为true时,||也是如此。

您可以在此处阅读更多信息:http://en.wikipedia.org/wiki/Short-circuit_evaluation从该页的表中,您可以看到&&等效于VB.NET中的AndAlso,我想您指的是它。

操作员&&/||&/|之间存在三个相关差异,官方文档对此进行了解释。总结如下:

1.&|矢量化

这意味着,如果要对向量执行元素逻辑运算,则应使用&|:

a = c(TRUE, TRUE, FALSE, FALSE)
b = c(TRUE, FALSE, TRUE, FALSE)
a | b
# [1]  TRUE  TRUE  TRUE FALSE
a || b
# [1] TRUE

对于&&/||,丢弃第一个之后的所有元素。当在长度超过1:的矢量上使用&&/||时,R的最新版本会生成有用的警告

In a || b : 'length(x) = 4 > 1' in coercion to 'logical(1)'

2.&&||短路

短路意味着只有当表达式的右侧尚未确定结果时,才会对其进行求值。几乎每种编程语言都对条件运算这样做,因为在编写if条件时,它会带来方便的习惯用法,例如:

if (length(x) > 0L && x[1L] == 42) …

此代码依赖于短路:如果没有短路,x为空,则代码将失败,因为右侧试图访问不存在的元素。如果没有短路,我们将不得不使用嵌套的if块,从而产生更详细的代码:

if (length(x) > 0L) {
    if (x[1L] == 42) …
}

一般来说,在条件表达式(ifwhile)中,即使不需要短路,也应该始终使用&&||:这更惯用,并导致更统一的代码。

3.&|可以执行逐位运算

在许多(大多数)编程语言中,&|实际上执行逐位算术,而不是布尔算术。也就是说,对于两个整数aba & b计算位和,而a | b计算<em]位或>。对于布尔值,按位运算和逻辑运算之间没有区别;但对于任意整数,结果不同。例如,大多数编程语言中的1 | 2 == 3

然而,对于R:R,这不是真的:R将&|的数字参数强制为逻辑值并执行布尔运算。

…除非两个参数都属于raw:类型

c(1, 3) | c(2, 4)
# [1] TRUE TRUE
as.raw(c(1, 3)) | as.raw(c(2, 4))
# [1] 03 07

值得注意的是,运算!(逻辑否定)和xor在使用raw自变量调用时也执行逐位算术。

从变更日志中,由于R 4.2.0调用长度大于1的&&||是一个警告:

呼叫&amp;或者长度大于1的参数||现在会发出警告(这将成为一个错误)。

并且由于4.3.0是一个错误:

呼叫&amp;或||LHS或长度大于1的RHS(如果评估)现在总是一个错误,报告形式为

"长度=4"强制为"逻辑(1)"

环境变量R_CHECK_LENGTH_1_LOGIC2不再有任何影响。

相关内容

  • 没有找到相关文章

最新更新