浅谈R语言中&&,||与&,|的区别
首先,从概念上讲,&&和&都属于逻辑运算符,但是,用起来还是有一些区别,概括地讲:
&&为值逻辑,&为位逻辑
说人话就是,&&是讲两个操作目的值做逻辑运算,无论操作对象是向量还是标量,返回值都是一个逻辑值;而&是讲两个对象按位比较,其返回值的长度与对象是标量还是向量有关.
看下面的例子,对于两个等长向量间的运算:
例1:
a<-c(TRUE,FALSE,FALSE,TRUE)
b<-c(FALSE,TRUE,FALSE,TRUE)
a&&b
a&b
结果如下:
[1] FALSE
[1] FALSE FALSE FALSE TRUE
1.懒惰的&&和||
可以看出,&&运算符在接收向量时,只取了第一个元素比较,然后返回逻辑值,那如果向量的第一个元素为NA呢,我们再来看一下:
例2:
b<-c(FALSE,TRUE,FALSE,TRUE)
c<-c(NA,TRUE)
b&&c
b||c
注意,这里不以NULL演示是因为c(NULL,TRUE)等价于c(TRUE),无意义
结果如下:
[1] FALSE
[1] NA
这里需要解释一下的是,如下运算规律的存在
> TRUE&&NA
> FALSE&&NA
结果:
[1] NA
[1] FALSE
简言之,就是&&和||只取向量的第一个元素做比较,即使这一次比较没有获得逻辑值(获得了NA),也会退出比较.
2.严格的&和|
从例1可以看出,&运算符返回了与对象等长的逻辑值向量,也就是说,&运算符是严格的,它将向量的每一对元素都进行了逻辑运算.那么当两个操作对象不等长时,&如何运算呢?
例3:
b<-c(FALSE,TRUE,FALSE,TRUE)
c<-c(NA,TRUE)
b&c
b|c
结果如下:
[1] FALSE TRUE FALSE TRUE
[1] NA TRUE NA TRUE
可以看到,&和|返回值长度始终等于参与运算的对象长度的最大值.上例的运算过程如下:
对两个运算对象同步遍历,对取出每一对元素进行比较,当有对象被遍历完,而另一对象并未遍历完成(两对象不等长),那么短对象将再次被遍历,直至长对象也被遍历完.
3.结论
- &&,||是短逻辑,只取操作对象的第一个值运算,具备短路规则,只返回一个逻辑值或NA
- &,|是长逻辑,循环遍历的取操作的对象的每一对值军算,直到每一个元素都参与了运算,其返回值长度等于操作对象长度的最大值
应用典例:按条件选择数据框-subset()函数
下表是用户提交的数据,我想将其中每一列都为空的行剔除掉,使用subset()函数如下
这里因为不能确定用户操作后,空的单元格是""还是NA,所以用了&来规避两种情况;
finalDF<-subset(finalDF,(!is.na(order1)& order1!='') |
(!is.na(product)& product!='') |
(!is.na(type) &type!='') |
(!is.na(parameter)¶meter!='' ) |
(!is.na(sn) &sn!='') |
(!is.na(data)&data!='' ) |
(!is.na(lsl)&lsl!='' ) |
(!is.na(usl) &usl!=''),select=order1:usl)#排除5列都为空的行
结果如下:
可以看到,空行可以被正确剔除,但如果不小心使用了||操作符,那么行的筛选将只以第一行的元素有关: