在R中,||和|有什么区别?

4

我知道"||"在大多数编程语言中,包括R语言中表示“或”的意思。但有时我看到人们使用“|”,而我不完全确定它的意思。它与"||"有什么区别呢?

谢谢。

2个回答

13
为了查阅R语言中的逻辑运算符帮助文档,请执行以下操作:
?`|`

或者
?`||`

两者都会带您到适当的帮助页面http://stat.ethz.ch/R-manual/R-patched/library/base/html/Logic.html

除非您输入一个向量或者无法正确评估的内容,否则您不会注意到任何区别:

> T|F
[1] TRUE
> T||F
[1] TRUE

但是当您使用向量时:

> c(T,T,F,F) || c(T,F,T,F)
[1] TRUE
> c(T,T,F,F) | c(T,F,T,F)
[1]  TRUE  TRUE  TRUE FALSE

同样适用于 &&&
> c(T,T,F,F) & c(T,F,T,F)
[1]  TRUE FALSE FALSE FALSE
> c(T,T,F,F) && c(T,F,T,F)
[1] TRUE

所以 |& 比较两个向量中对应位置的元素,并用此来填充一个新的逻辑向量。如果其中一个向量比另一个短,它的元素将从开头开始 "循环使用":

> c(T, F, T, F) | c(T, T, F, F, T, F) #first 2 elements of left vector recycled
[1]  TRUE  TRUE  TRUE FALSE  TRUE FALSE
Warning message:
In c(T, F, T, F) | c(T, T, F, F, T, F) :
  longer object length is not a multiple of shorter object length
> c(T, F, T, F, T, F) | c(T, T, F, F, T, F) #what actually got evaluated
[1]  TRUE  TRUE  TRUE FALSE  TRUE FALSE

请注意||&&只查看向量的第一个元素,因此例如:

> c(T,T,T,T) && c(F,T,T,T) #only does T & F
[1] FALSE
> c(F,T,T,T) || c(F,T,T,T) #only does F | F
[1] FALSE
> c(T,F,F,F) && c(T,F,F,F) #only does T & T
[1] TRUE
> c(T,F,F,F) || c(F,F,F,F) #only does F | F
[1] TRUE

对于无法求值的输入,||&&更加巧妙:它们从左到右"短路"。如果||的左边输入为TRUE(因此结果必须为TRUE),或者&&的左边输入为FALSE(因此结果必须为FALSE),则无需评估右边的输入。保留HTML标签。
> x
Error: object 'x' not found
> exists("x")
[1] FALSE
> F & x # evaluates right input, fails
Error: object 'x' not found
> F && x # skips right input, already knows result F
[1] FALSE
> T && x # can't skip right input, so fails
Error: object 'x' not found
> T | x
Error: object 'x' not found
> T || x # skips right input, already knows result T
[1] TRUE

如果您想安全地检查某些内容,这将非常有用:

> (x > 20)
Error: object 'x' not found
> exists("x") & (x > 20) # still evaluated right input, fails
Error: object 'x' not found
> exists("x") && (x > 20) # safe
[1] FALSE

10

运算符&&/||&/|之间有三个相关差异,这些差异在官方文档中有解释。以下是总结:

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计算按位或。对于布尔值,按位和逻辑操作没有区别;但对于任意整数,结果是不同的。例如,在大多数编程语言中,1 | 2 == 3
然而,这在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时,它们也会执行位运算。

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