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

Cat*_*ath 5 r

我经常使用all函数,每当我得到TRUE,我发现自己检查比较的所有元素都不是NULL或为空,因为这可能会给出错误的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)
Run Code Online (Sandbox Code Playgroud)

因此,在第二种情况下,如果我不检查每个元素all,我将使用我的代码,认为一切顺利,当然,最终结果将是不正确的.

我没有检查我all拨打电话的元素,而是可以添加一个length电话:(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返回,NA或者FALSE当任何一个元素的长度为0时(all帮助对该主题没有多大帮助)或者是否有替代函数可以做到这一点?

编辑

感谢@Metrics,有一个替代功能identical:

identical(y[y>5 & y<0],z[z>5 & z<10])
[1] FALSE
Run Code Online (Sandbox Code Playgroud)

虽然在这种情况下identical没有返回TRUE,但它仍然没有警告我出现了问题......

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

Mar*_*pov 6

文档all清楚地说:

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

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

所以没有办法获得你想要的结果all.

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

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

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

不要直接在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)
 }
Run Code Online (Sandbox Code Playgroud)

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

y[y>5 & y<10]  %=%  z[z>5 & z<10]
# [1] TRUE
Run Code Online (Sandbox Code Playgroud)

并且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
Run Code Online (Sandbox Code Playgroud)