我经常使用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,但它仍然没有警告我出现了问题......
理想的解决方案会返回一个警告,例如,一个元素是空的.
文档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)