当与`NULL`或空对象进行比较时,如何避免`all`函数返回`TRUE`

时间:2015-02-13 14:42:37

标签: r

我经常使用all函数,每当我得到TRUE时,我发现自己检查比较的所有元素都不是NULL或是空的,因为这可能会导致错误{ {1}}结果。

示例:

TRUE

所以,在第二种情况下,如果我不检查y<-1:10 z<-5:15 # I make a comparison which is really true all(y[y>5 & y<10]==z[z>5 & z<10]) [1] TRUE # Now I make a typo because I often do, but I don't notice: all(y[y>5 & y<0]==z[z>5 & z<10]) [1] TRUE # the result is also true but only because y[y>5 & y<0] is empty: y[y>5 & y<0] #integer(0) 的每个元素,我将使用我的代码,认为一切顺利,当然,最终结果将是不正确的。< / p>

我可以添加一个all来电:all,而不是检查我在length电话中添加的元素,但这似乎相当乏味...

当任何一个元素的长度为0((all(y[y>5 & y<0]==z[z>5 & z<10]) & length(y[y>5 & y<0])>0 & length(z[z>5 & z<10]>0)帮助对该主题不是很有帮助)时,有没有办法让all返回NAFALSE或者是还有另一种能做到这一点的功能吗?

修改

感谢@Metrics,还有一个功能all的替代方案:

identical

虽然在这种情况下identical(y[y>5 & y<0],z[z>5 & z<10]) [1] FALSE 没有返回identical,但它仍然不会警告我出现了问题......

理想的解决方案会返回一个警告,例如,一个元素是空的。

2 个答案:

答案 0 :(得分:6)

all的文档清楚地说:

  

所有(逻辑(0))为真是一个有用的约定:它确保

     

all(all(x),all(y))== all(x,y),即使x的长度为零。

因此无法使用all获得所需的结果。

正如评论中所述,identicalall.equal与您的请求更为匹配。但是,identical如果比较的对象长度不同,则不会发出警告。 all.equal的缺点是在不同长度的情况下它不会返回逻辑值:

all.equal(y[y>5 & y<0],z[z>5 & z<10])
# [1] "Numeric: lengths (0, 4) differ"

我相信官方文档建议不要在all.equal表达式中直接使用if

  

如果使用表达式,请不要直接使用all.equal   isTRUE(all.equal(....))或相同的相同。

但是,isTRUE(all.equal(y[y>5 & y<0],z[z>5 & z<10]))不会告诉您不同的长度。

<强> [解决]

您可以为此目的编写自己的函数,并为方便起见添加一些语法糖:

'%=%' <- function(a,b) {
   if (length(a)!=length(b)) warning('Objects are of different length')
   identical(a,b)
 }

如果对象相同,它将返回TRUE

y[y>5 & y<10]  %=%  z[z>5 & z<10]
# [1] TRUE

FALSE如果对象不同(+警告,如果它们的长度不同):

y[y>5 & y<0]  %=%  z[z>5 & z<10]
#  [1] FALSE
#  Warning message:
#    In y[y > 5 & y < 0] %=% z[z > 5 & z < 10] :
#    Objects are of different length

答案 1 :(得分:3)

我认为您不应该为此目的使用identicalall.equal。如前所述,后者并不总是返回逻辑向量,而第一个更严格,应该仅用于检查两个对象是否真的相同。考虑这个例子:

y<-setNames(1:10,letters[1:10])
z<-5:15
identical(y[y>5 & y<10],z[z>5 & z<10])

它会FALSE,因为y有名字。 all功能是可行的方法。如果您真的对零长度问题感到困扰,请尝试:

myAll <- function(x,na.rm=FALSE) {
   if (length(x)==0) {
      warning("zero length argument")
      return(TRUE)
   }
   all(x,na.rm=na.rm)
}

当然,您可以在x长度为零时更改行为,也可以如前所述定义二元运算符。