The difference between & and && in R

2019-01-20 11:20发布

问题:

I have read

http://stat.ethz.ch/R-manual/R-devel/library/base/html/Logic.html

and the difference between & and && doesn't make sense. For example :

> c(1, 2, 3) & c(1,2,3)
[1] TRUE TRUE TRUE

According to the link this is expected behavior. It is doing an element-wise comparison of the two vectors.

So I test again...

> c(1, 2, 3) && c(1,2,3)
[1] TRUE

This also returns what was expected.

But then I change a value...

> c(1, 2, 3) && c(1,3,3)
[1] TRUE

Still expected because it short circuits on the first element.

> c(1, 2, 3) & c(1,3,3)
[1] TRUE TRUE TRUE

This however lost me. These two vectors should not be equal.

回答1:

& is a logical operator so R coverts your quantities to logical values before comparison. For numeric values any non-0 (and non-NA/Null/NaN stuff) gets the value TRUE and 0 gets FALSE. So with that said things make quite a bit of sense

> as.logical(c(1,2,3))
[1] TRUE TRUE TRUE
> as.logical(c(1,3,3))
[1] TRUE TRUE TRUE
> as.logical(c(1,2,3)) & as.logical(c(1,2,3))
[1] TRUE TRUE TRUE
> as.logical(c(1,2,3)) & as.logical(c(1,3,3))
[1] TRUE TRUE TRUE


回答2:

Consider this, then it should be clear:

as.logical(c(0,1,2,3,4))
#[1] FALSE  TRUE  TRUE  TRUE  TRUE

So...

c(1,2,3) & c(1,3,3)
#[1] TRUE TRUE TRUE

is equivalent to:

c(TRUE,TRUE,TRUE) & c(TRUE,TRUE,TRUE)

...which compares by element using & and returns c(TRUE,TRUE,TRUE)

For reference:

test <- c(NA,NaN,-Inf,-1,-0.5,0,0.5,1,2,Inf)
data.frame(test,as.logical(test))

#   test as.logical.test.
#1    NA               NA
#2   NaN               NA
#3  -Inf             TRUE
#4  -1.0             TRUE
#5  -0.5             TRUE
#6   0.0            FALSE
#7   0.5             TRUE
#8   1.0             TRUE
#9   2.0             TRUE
#10  Inf             TRUE


回答3:

The "&" operator is only an element -by-element logical AND when the vectors are of equal length. That why you should also expect this result:

 c(0,1,2,3,4) & 1
[1] FALSE  TRUE  TRUE  TRUE  TRUE  # due to argument recycling

Notice that it is not comparing numerical values but only after coercion to type "logical", and any non-zero value will be TRUE:

seq(0,1,by=.2) & -1
[1] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE

"&&" only compares the first element of its first argument to the first argument of the second and issues a warning (but not an error) if either are longer than a single element.

If you want to test for equality then use "==".