On Sat, Dec 12, 2015 at 6:08 AM, Hadley Wickham <h.wick...@gmail.com> wrote: > On Sat, Dec 12, 2015 at 3:54 AM, Martin Maechler > <maech...@stat.math.ethz.ch> wrote: >>>>>>> Henrik Bengtsson <henrik.bengts...@gmail.com> >>>>>>> on Fri, 11 Dec 2015 08:20:55 -0800 writes: >> >> > On Fri, Dec 11, 2015 at 8:10 AM, David Winsemius >> <dwinsem...@comcast.net> wrote: >> >> >> >>> On Dec 11, 2015, at 5:38 AM, Dario Beraldi <dario.bera...@gmail.com> >> wrote: >> >>> >> >>> Hi All, >> >>> >> >>> I'd like to understand the reason why stopifnot(logical(0) == x) >> doesn't >> >>> (never?) throw an exception, at least in these cases: >> >> >> >> The usual way to test for a length-0 logical object is to use >> length(): >> >> >> >> x <- logical(0) >> >> >> >> stopifnot( !length(x) & mode(x)=="logical" ) >> >> > I found >> >> > stopifnot(!length(x), mode(x) == "logical") >> >> > more helpful when troubleshooting, because it will tell you whether >> > it's !length(x) or mode(x) == "logical" that is FALSE. It's as if you >> > wrote: >> >> > stopifnot(!length(x)) >> > stopifnot(mode(x) == "logical") >> >> > /Henrik >> >> Yes, indeed, thank you Henrik --- and Jeff Newmiller who's nice >> humorous reply added other relevant points. >> >> As author stopifnot(), I do agree with Dario's "gut feeling" >> that stopifnot() "somehow ought to do the right thing" >> in cases such as >> >> stopifnot(dim(x) == c(3,4)) >> >> which is really subtle version of his cases >> {But the gut feeling is wrong, as I argue from now on}. > > Personally, I think the problem there is that people forget that == is > vectorised, and for a non-vectorised equality check you really should > use identical: > > stopifnot(identical(dim(x), c(3,4)))
Kids, this one of the rare cases where you should not listen to Hadley ;) Because, > x <- matrix(1:12, nrow=3, ncol=4) > dim(x) [1] 3 4 > identical(dim(x), c(3,4)) [1] FALSE Why, because: > storage.mode(dim(x)) [1] "integer" > storage.mode(c(3,4)) [1] "double" My rule of thumb is that identical() is awesome, but you really have to know the inner bits and pieces (*). When in doubt, use all.equal(), e.g. > all.equal(dim(x), c(3,4)) [1] TRUE Related to Hadley's point, is that using all(x == y) is risky because R loops of one of the two vectors if one is longer than the other, e.g. > all(dim(x) == c(3,4)) [1] TRUE > all(dim(x) == c(3,4,3,4)) [1] TRUE > all(dim(x) == c(3,4,3,4,3,4)) [1] TRUE so one really need to check the lengths as well, e.g. > all(length(dim(x)) == length(c(3,4)), dim(x) == c(3,4)) [1] TRUE (*) ADVANCED: I would say its risky to use: > identical(dim(x), c(3L,4L)) [1] TRUE because, who knows, in a future version of R we might see matrices/arrays that support dimensions longer than .Machine$integer.max which in case dimensions may be stored as doubles. This is what we already have for very long vectors today, cf. help("length"). Henrik > > Hadley > > -- > http://had.co.nz/ ______________________________________________ R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.