为什么空逻辑向量通过stopifnot()检查?

Today I found that some of my stopifnot() tests are failing because the passed arguments evaluate to empty logical vectors.

这是一个例子:

stopifnot(iris$nosuchcolumn == 2)  # passes without error

这是非常不直观的,似乎与其他一些行为相矛盾。考虑:

isTRUE(logical())
> FALSE

stopifnot(logical())
# passes

So stopifnot() passes even when this argument is not TRUE.
But furthermore, the behaviour of the above is different with different types of empty vectors.

isTRUE(numeric())
> FALSE

stopifnot(numeric())
# Error: numeric() are not all TRUE

上面是否有逻辑,还是应该将其视为错误?

评论
欧美式接吻
欧美式接吻

akrun和r2evans的评论很明显。

However, to give details on why specifically this happens and why you're confused vs. isTRUE() behavior, note that stopifnot() checks for three things; the check is (where r is the result of the expression you pass):

if (!(is.logical(r) && !anyNA(r) && all(r)))

因此,让我们看一下:

is.logical(logical())
# [1] TRUE
!anyNA(logical())
# [1] TRUE
all(logical())
# [1] TRUE

is.logical(numeric())
# [1] FALSE
!anyNA(numeric())
# [1] TRUE
all(numeric())
# [1] TRUE

So, the only reason why logical() passes while numeric() fails is because numeric() is not "logical," as suggested by akrun. For this reason, you should avoid checks that may result in logical vectors of length 0, as suggested by r2evans.

点赞
评论