我经常使用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
返回NA
或FALSE
或者是还有另一种能做到这一点的功能吗?
修改
感谢@Metrics,还有一个功能all
的替代方案:
identical
虽然在这种情况下identical(y[y>5 & y<0],z[z>5 & z<10])
[1] FALSE
没有返回identical
,但它仍然不会警告我出现了问题......
理想的解决方案会返回一个警告,例如,一个元素是空的。
答案 0 :(得分: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"
我相信官方文档建议不要在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)
我认为您不应该为此目的使用identical
或all.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
长度为零时更改行为,也可以如前所述定义二元运算符。