SFu*_*n28 232 r logical-operators or-operator boolean-operations and-operator
根据R输入语言定义,之间的差&和&&(相应地|和||)是,虽然后者不是前者被矢量.
根据帮助文本,我读到的差异类似于"And"和"AndAlso"(相应地"Or"和"OrElse")之间的区别......意思是:如果不是所有的评估都不是(即如果A为真,则A或B或C始终为真,因此请停止评估A是否为真)
有人会在这里光明吗?另外,R中是否有AndAlso和OrElse?
Aar*_*ica 321
较短的是矢量化的,这意味着它们可以返回一个向量,如下所示:
((-2:2) >= 0) & ((-2:2) <= 0)
# [1] FALSE FALSE TRUE FALSE FALSE
Run Code Online (Sandbox Code Playgroud)
较长的形式从左到右评估只检查每个向量的第一个元素,所以上面给出
((-2:2) >= 0) && ((-2:2) <= 0)
# [1] FALSE
Run Code Online (Sandbox Code Playgroud)
正如帮助页面所说,这使得更长的形式"适合于编程控制流,并且在if子句中通常是首选的."
因此,只有在确定向量为长度为1时才要使用长格式.
你绝对应该确定你的向量只有长度为1,例如在它们只返回长度为1的布尔值的情况下.如果向量的长度可能> 1,则要使用短格式.因此,如果您不完全确定,则应首先检查,或使用简短形式,然后使用all和any将其缩短为长度1以用于控制流语句,例如if.
函数all和函数any通常用于矢量化比较的结果,以分别查看所有或任何比较是否为真.这些函数的结果肯定是长度为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
Run Code Online (Sandbox Code Playgroud)
最后,参见The R Inferno中的 8.2.17节,标题为"and andandand".
42-*_*42- 32
关于"短路"的答案可能具有误导性,但有一些道理(见下文).在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
Run Code Online (Sandbox Code Playgroud)
The*_*heo 23
&&而||在所谓的"短路".这意味着如果第一个操作数足以确定表达式的值,它们将不会计算第二个操作数.
例如,如果第一个操作数&&为false,则评估第二个操作数没有意义,因为它不能更改表达式的值(false && true并且false && false都是false).第||一个操作数为真时也是如此.
你可以阅读更多关于此这里:http://en.wikipedia.org/wiki/Short-circuit_evaluation从该网页上表中可以看到,&&就相当于AndAlso在VB.NET,我假设你指的是.
运算符/和/之间存在三个相关差异,官方文档中对此进行了解释。这里\xe2\x80\x99s是一个总结:&&||&|
&和|被矢量化这意味着如果您想对向量执行按元素逻辑运算,您应该使用&and |:
a = c(TRUE, TRUE, FALSE, FALSE)\nb = c(TRUE, FALSE, TRUE, FALSE)\n\na | b\n# [1] TRUE TRUE TRUE FALSE\n\na || b\n# Error in a || b : \'length = 4\' in coercion to \'logical(1)\'\nRun Code Online (Sandbox Code Playgroud)\n在以前版本的 R 中,a || b( 和a && b) 不会导致错误。相反,这些操作会默默地截断输出(仅返回第一个元素;在导致此错误之前,它会在 R 4.2 中短暂引发警告)。
&&和||短路短路意味着仅当左侧尚未确定结果时才计算表达式的右侧。几乎每种编程语言都对条件操作执行此操作,因为它在编写if条件时会产生方便的习惯用法,例如:
if (length(x) > 0L && x[1L] == 42) \xe2\x80\xa6\nRun Code Online (Sandbox Code Playgroud)\n此代码依赖于短路:如果没有它,如果为x空,则代码将失败,因为右侧尝试访问不存在的元素。如果没有短路,我们将不得不使用嵌套if块,从而导致更冗长的代码:
if (length(x) > 0L) {\n if (x[1L] == 42) \xe2\x80\xa6\n}\nRun Code Online (Sandbox Code Playgroud)\n作为一般规则,在条件表达式 ( if, while) 中,您应该始终使用&&and ||,即使不需要短路:它更惯用,并导致更统一的代码。
&可以|进行按位运算在许多(大多数?)编程语言中,&实际上|执行按位算术而不是布尔算术。即,对于两个整数a和b,a & b计算按位与,并a | b计算按位或。对于布尔值,按位运算和逻辑运算之间没有区别;但对于任意整数,结果不同。例如,1 | 2 == 3在大多数编程语言中。
然而,对于 R 来说情况并非&如此:R 将和 的数字参数强制转换|为逻辑值并执行布尔算术。
\xe2\x80\xa6 除非两个参数都是类型raw:
c(1, 3) | c(2, 4)\n# [1] TRUE TRUE\n\nas.raw(c(1, 3)) | as.raw(c(2, 4))\n# [1] 03 07\nRun Code Online (Sandbox Code Playgroud)\n值得注意的是,当使用参数调用时,操作!(逻辑非)也会执行按位算术。xorraw