Re: [R] stopifnot with logical(0)
On 14/12/2015 11:45 AM, Hadley Wickham wrote: >> I wonder if R is missing an equality operator for this case. Currently: >> >> * == is suboptimal because it's vectorised >> * all.equal is suboptimal because it returns TRUE or a text string >> * identical is suboptimal because it doesn't do common coercions >> >> Do we need another function (equals()?) that uses the same coercion >> rules as == but isn't vectorised? (Like == it would only work with >> vectors, so you'd still need identical() for (e.g.) comparing >> environments) > > I don't think so. We already have all(), so all(x == y) would do what you > want. But that recycles, which is what we're trying to avoid here. I think this is too special a case to need a function. Usually all(x == y) is the test you want, because so many R functions will recycle. It's not so when x is the dim of an array. So I could see a weak argument for an equalDim() function, but I think it's better just to use stopifnot(length(dim) == 2, all(dim == c(3,4))) I know the all() in the second arg isn't needed, but I think it makes the intention clearer. I think there would be less confusion if stopifnot() required its args to be single logical values, so I usually try to use it that way. Duncan Murdoch __ 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.
Re: [R] stopifnot with logical(0)
>> I wonder if R is missing an equality operator for this case. Currently: >> >> * == is suboptimal because it's vectorised >> * all.equal is suboptimal because it returns TRUE or a text string >> * identical is suboptimal because it doesn't do common coercions >> >> Do we need another function (equals()?) that uses the same coercion >> rules as == but isn't vectorised? (Like == it would only work with >> vectors, so you'd still need identical() for (e.g.) comparing >> environments) > > I don't think so. We already have all(), so all(x == y) would do what you > want. But that recycles, which is what we're trying to avoid here. 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.
Re: [R] stopifnot with logical(0)
Hadley wrote > * all.equal is suboptimal because it returns TRUE or a text string That feature works ok with stopifnot(): > stopifnot(all.equal("one", 1)) Error: all.equal("one", 1) are not all TRUE and I suppose stopifnot could be enhanced to print the text strings that all.equal() returns so the user has a better idea of what went wront. I find that all.equal's comparing of names gets in the way of the intent of stopifnot > stopifnot(all.equal(1:2, c(X=1,Y=2))) Error: all.equal(1:2, c(X = 1, Y = 2)) is not TRUE When we use things like all.equal() or new operators that do non-recycycling binary operations we may make things simpler for the programmer, but harder for the user. I think the user would rather see a specific message about what is wrong rather than a note that an obscure function did not return TRUE. > f <- function(x) { stopifnot(length(x)==1, x>0) seq_len(x) } > f(1:3) Error: length(x) == 1 is not TRUE > f(-4) Error: x > 0 is not TRUE > f(4) [1] 1 2 3 4 Another step in this direction is to change the call to stop() in stopifnot from what I assume is stop(message, call.=FALSE) to stop(simpleError(message, sys.call(-1))) so the error message included where error was: > f(-1) Error in f(-1) : x > 0 is not TRUE (This is Bug 16188.) Bill Dunlap TIBCO Software wdunlap tibco.com On Mon, Dec 14, 2015 at 8:10 AM, Hadley Wickham wrote: > On Sat, Dec 12, 2015 at 1:51 PM, Martin Maechler > wrote: >>> Hadley Wickham >>> on Sat, 12 Dec 2015 08:08:54 -0600 writes: >> >> > On Sat, Dec 12, 2015 at 3:54 AM, Martin Maechler >> > wrote: >> >>> Henrik Bengtsson on >> >>> Fri, 11 Dec 2015 08:20:55 -0800 writes: >> >> >> >> > On Fri, Dec 11, 2015 at 8:10 AM, David Winsemius >> >> wrote: >> >> >> >> >> >>> On Dec 11, 2015, at 5:38 AM, Dario Beraldi >> >> 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))) >> >> You are right "in theory" but practice is less easy: >> identical() tends to be too subtle for many users ... even >> yourself (;-), not really of course!), Hadley, in the above case: >> >> Your stopifnot() would *always* stop, i.e., signal an error >> because typically all dim() methods return integer, and c(3,4) >> is double. >> So, if even Hadley gets it wrong so easily, I wonder if its good >> to advertize to always use identical() in such cases. >> I indeed would quite often use identical() in such tests, and >> you'd too and would quickly find and fix the "trap" of course.. >> So you are mostly right also in my opinion... > > Ooops, yes - but you would discover this pretty quickly if you weren't > coding in a email client ;) > > I wonder if R is missing an equality operator for this case. Currently: > > * == is suboptimal because it's vectorised > * all.equal is suboptimal because it returns TRUE or a text string > * identical is suboptimal because it doesn't do common coercions > > Do we need another function (equals()?) that uses the same coercion > rules as == but isn't vectorised? (Like == it would only work with > vectors, so you'd still need identical() for (e.g.) comparing > environments) > > 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.h
Re: [R] stopifnot with logical(0)
On 14/12/2015 11:10 AM, Hadley Wickham wrote: On Sat, Dec 12, 2015 at 1:51 PM, Martin Maechler wrote: >> Hadley Wickham >> on Sat, 12 Dec 2015 08:08:54 -0600 writes: > > > On Sat, Dec 12, 2015 at 3:54 AM, Martin Maechler > > wrote: > >>> Henrik Bengtsson on > >>> Fri, 11 Dec 2015 08:20:55 -0800 writes: > >> > >> > On Fri, Dec 11, 2015 at 8:10 AM, David Winsemius > >> wrote: > >> >> > >> >>> On Dec 11, 2015, at 5:38 AM, Dario Beraldi > >> 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))) > > You are right "in theory" but practice is less easy: > identical() tends to be too subtle for many users ... even > yourself (;-), not really of course!), Hadley, in the above case: > > Your stopifnot() would *always* stop, i.e., signal an error > because typically all dim() methods return integer, and c(3,4) > is double. > So, if even Hadley gets it wrong so easily, I wonder if its good > to advertize to always use identical() in such cases. > I indeed would quite often use identical() in such tests, and > you'd too and would quickly find and fix the "trap" of course.. > So you are mostly right also in my opinion... Ooops, yes - but you would discover this pretty quickly if you weren't coding in a email client ;) I wonder if R is missing an equality operator for this case. Currently: * == is suboptimal because it's vectorised * all.equal is suboptimal because it returns TRUE or a text string * identical is suboptimal because it doesn't do common coercions Do we need another function (equals()?) that uses the same coercion rules as == but isn't vectorised? (Like == it would only work with vectors, so you'd still need identical() for (e.g.) comparing environments) I don't think so. We already have all(), so all(x == y) would do what you want. Duncan Murdoch __ 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.
Re: [R] stopifnot with logical(0)
On Sat, Dec 12, 2015 at 1:51 PM, Martin Maechler wrote: >> Hadley Wickham >> on Sat, 12 Dec 2015 08:08:54 -0600 writes: > > > On Sat, Dec 12, 2015 at 3:54 AM, Martin Maechler > > wrote: > >>> Henrik Bengtsson on > >>> Fri, 11 Dec 2015 08:20:55 -0800 writes: > >> > >> > On Fri, Dec 11, 2015 at 8:10 AM, David Winsemius > >> wrote: > >> >> > >> >>> On Dec 11, 2015, at 5:38 AM, Dario Beraldi > >> 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))) > > You are right "in theory" but practice is less easy: > identical() tends to be too subtle for many users ... even > yourself (;-), not really of course!), Hadley, in the above case: > > Your stopifnot() would *always* stop, i.e., signal an error > because typically all dim() methods return integer, and c(3,4) > is double. > So, if even Hadley gets it wrong so easily, I wonder if its good > to advertize to always use identical() in such cases. > I indeed would quite often use identical() in such tests, and > you'd too and would quickly find and fix the "trap" of course.. > So you are mostly right also in my opinion... Ooops, yes - but you would discover this pretty quickly if you weren't coding in a email client ;) I wonder if R is missing an equality operator for this case. Currently: * == is suboptimal because it's vectorised * all.equal is suboptimal because it returns TRUE or a text string * identical is suboptimal because it doesn't do common coercions Do we need another function (equals()?) that uses the same coercion rules as == but isn't vectorised? (Like == it would only work with vectors, so you'd still need identical() for (e.g.) comparing environments) 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.
Re: [R] stopifnot with logical(0)
> "DM" == Duncan Murdoch > on Sat, 12 Dec 2015 09:05:04 -0500 writes: DM> On 12/12/2015 8:44 AM, peter dalgaard wrote: >> >>> On 12 Dec 2015, at 10:54 , Martin Maechler >>> wrote: >>> >>> My conclusion: Breaking such a fundamental lemma of >>> logic as "the empty set is always true" >> >> Umm, that doesn't make sense to me. Surely you mean that >> "an AND-operation over an empty index set is TRUE"? A >> similar OR operation is FALSE, i.e. they behave like >> empty products and sums, respectively. >> DM> How about "the empty set is all true, and all false." or, what the I *meant* with the above: "All statements about elements of the empty set are true" ((and I still like the short form, even though it is not correct strictly logically/mathematically)) Of course, Peter is correct, and that any(logical(0)) is FALSE is really the only sensical way. __ 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.
Re: [R] stopifnot with logical(0)
> On 13 Dec 2015, at 20:31 , William Dunlap wrote: > >> as Bill or Jeff explained, "the empty set is always true" > > My wording was that any(logical(0)) is FALSE because "there are no > TRUEs in logical(0)". Yes. My mind still boggles over how the empty set slipped into Boolean algebra. Another way of flogging the horse is to say that we want[*] any(c(x,y)) == any(x) | any(y) even if x has length 0. In that case c(x,y) == y, so we must have any(y) == any(logical(0)) | any(y) which holds for all y if and only if any(logical(0)) is FALSE. Also, as I tried to say before, any() is to "|" what sum() is to "+" and what all() is to "&" and prod() is to "*". All the operators have an identity element, namely FALSE, 0, TRUE, and 1 respectively, and the generic convention is that for an empty vector, we return the identity element, for the reason given above. Peter D. [*] Assuming logical vectors here. Coercion might well do odd things... > Bill Dunlap > TIBCO Software > wdunlap tibco.com > > > On Sat, Dec 12, 2015 at 1:54 AM, Martin Maechler > wrote: >>> Henrik Bengtsson >>>on Fri, 11 Dec 2015 08:20:55 -0800 writes: >> >>> On Fri, Dec 11, 2015 at 8:10 AM, David Winsemius >>> wrote: > On Dec 11, 2015, at 5:38 AM, Dario Beraldi > 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}. >> >> Someone writing the above would want stopifnot() to stop in the >> case where x is a simple vector instead of a >> matrix/data.frame/... with dimensions c(3,4) ... but it will not >> because, as Bill or Jeff explained, "the empty set is always >> true", and so yes indeed, you have to care about length-0 >> expressions in stopifnot(). >> >> Indeed, in the past, I had thought of "improving" stopifnot() >> by giving a warning or even stop() for logical(0) expressions, >> but I quickly dismissed that idea after some experiments. >> >> My conclusion: Breaking such a fundamental lemma of logic as >> "the empty set is always true" >> will lead to all kinds of illogical situations ... so don't do that! >> >> Martin Maechler, >> ETH Zurich >> >> __ >> 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. > > __ > 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. -- Peter Dalgaard, Professor, Center for Statistics, Copenhagen Business School Solbjerg Plads 3, 2000 Frederiksberg, Denmark Phone: (+45)38153501 Office: A 4.23 Email: pd@cbs.dk Priv: pda...@gmail.com __ 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.
Re: [R] stopifnot with logical(0)
> as Bill or Jeff explained, "the empty set is always true" My wording was that any(logical(0)) is FALSE because "there are no TRUEs in logical(0)". Bill Dunlap TIBCO Software wdunlap tibco.com On Sat, Dec 12, 2015 at 1:54 AM, Martin Maechler wrote: >> Henrik Bengtsson >> on Fri, 11 Dec 2015 08:20:55 -0800 writes: > > > On Fri, Dec 11, 2015 at 8:10 AM, David Winsemius > wrote: > >> > >>> On Dec 11, 2015, at 5:38 AM, Dario Beraldi > 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}. > > Someone writing the above would want stopifnot() to stop in the > case where x is a simple vector instead of a > matrix/data.frame/... with dimensions c(3,4) ... but it will not > because, as Bill or Jeff explained, "the empty set is always > true", and so yes indeed, you have to care about length-0 > expressions in stopifnot(). > > Indeed, in the past, I had thought of "improving" stopifnot() > by giving a warning or even stop() for logical(0) expressions, > but I quickly dismissed that idea after some experiments. > > My conclusion: Breaking such a fundamental lemma of logic as > "the empty set is always true" > will lead to all kinds of illogical situations ... so don't do that! > > Martin Maechler, > ETH Zurich > > __ > 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. __ 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.
Re: [R] stopifnot with logical(0)
> Hadley Wickham > on Sat, 12 Dec 2015 08:08:54 -0600 writes: > On Sat, Dec 12, 2015 at 3:54 AM, Martin Maechler > wrote: >>> Henrik Bengtsson on >>> Fri, 11 Dec 2015 08:20:55 -0800 writes: >> >> > On Fri, Dec 11, 2015 at 8:10 AM, David Winsemius >> wrote: >> >> >> >>> On Dec 11, 2015, at 5:38 AM, Dario Beraldi >> 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))) You are right "in theory" but practice is less easy: identical() tends to be too subtle for many users ... even yourself (;-), not really of course!), Hadley, in the above case: Your stopifnot() would *always* stop, i.e., signal an error because typically all dim() methods return integer, and c(3,4) is double. So, if even Hadley gets it wrong so easily, I wonder if its good to advertize to always use identical() in such cases. I indeed would quite often use identical() in such tests, and you'd too and would quickly find and fix the "trap" of course.. So you are mostly right also in my opinion... Martin __ 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.
Re: [R] stopifnot with logical(0)
On Sat, Dec 12, 2015 at 6:08 AM, Hadley Wickham wrote: > On Sat, Dec 12, 2015 at 3:54 AM, Martin Maechler > wrote: >>> Henrik Bengtsson >>> on Fri, 11 Dec 2015 08:20:55 -0800 writes: >> >> > On Fri, Dec 11, 2015 at 8:10 AM, David Winsemius >> wrote: >> >> >> >>> On Dec 11, 2015, at 5:38 AM, Dario Beraldi >> 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.
Re: [R] stopifnot with logical(0)
On 12/12/2015 9:08 AM, Hadley Wickham wrote: On Sat, Dec 12, 2015 at 3:54 AM, Martin Maechler wrote: Henrik Bengtsson on Fri, 11 Dec 2015 08:20:55 -0800 writes: > On Fri, Dec 11, 2015 at 8:10 AM, David Winsemius wrote: >> >>> On Dec 11, 2015, at 5:38 AM, Dario Beraldi 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))) identical() is a little pickier than people might think: > identical(dim(matrix(0, 3,4)), c(3,4)) [1] FALSE > identical(dim(matrix(0, 3,4)), c(3L,4L)) [1] TRUE Duncan Murdoch __ 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.
Re: [R] stopifnot with logical(0)
On 12/12/2015 8:44 AM, peter dalgaard wrote: On 12 Dec 2015, at 10:54 , Martin Maechler wrote: My conclusion: Breaking such a fundamental lemma of logic as "the empty set is always true" Umm, that doesn't make sense to me. Surely you mean that "an AND-operation over an empty index set is TRUE"? A similar OR operation is FALSE, i.e. they behave like empty products and sums, respectively. How about "the empty set is all true, and all false." __ 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.
Re: [R] stopifnot with logical(0)
On Sat, Dec 12, 2015 at 3:54 AM, Martin Maechler wrote: >> Henrik Bengtsson >> on Fri, 11 Dec 2015 08:20:55 -0800 writes: > > > On Fri, Dec 11, 2015 at 8:10 AM, David Winsemius > wrote: > >> > >>> On Dec 11, 2015, at 5:38 AM, Dario Beraldi > 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))) 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.
Re: [R] stopifnot with logical(0)
> On 12 Dec 2015, at 10:54 , Martin Maechler wrote: > > My conclusion: Breaking such a fundamental lemma of logic as > "the empty set is always true" Umm, that doesn't make sense to me. Surely you mean that "an AND-operation over an empty index set is TRUE"? A similar OR operation is FALSE, i.e. they behave like empty products and sums, respectively. -- Peter Dalgaard, Professor, Center for Statistics, Copenhagen Business School Solbjerg Plads 3, 2000 Frederiksberg, Denmark Phone: (+45)38153501 Office: A 4.23 Email: pd@cbs.dk Priv: pda...@gmail.com __ 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.
Re: [R] stopifnot with logical(0)
> Henrik Bengtsson > on Fri, 11 Dec 2015 08:20:55 -0800 writes: > On Fri, Dec 11, 2015 at 8:10 AM, David Winsemius wrote: >> >>> On Dec 11, 2015, at 5:38 AM, Dario Beraldi 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}. Someone writing the above would want stopifnot() to stop in the case where x is a simple vector instead of a matrix/data.frame/... with dimensions c(3,4) ... but it will not because, as Bill or Jeff explained, "the empty set is always true", and so yes indeed, you have to care about length-0 expressions in stopifnot(). Indeed, in the past, I had thought of "improving" stopifnot() by giving a warning or even stop() for logical(0) expressions, but I quickly dismissed that idea after some experiments. My conclusion: Breaking such a fundamental lemma of logic as "the empty set is always true" will lead to all kinds of illogical situations ... so don't do that! Martin Maechler, ETH Zurich __ 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.
Re: [R] stopifnot with logical(0)
On Fri, Dec 11, 2015 at 8:10 AM, David Winsemius wrote: > >> On Dec 11, 2015, at 5:38 AM, Dario Beraldi 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 > > >> >> stopifnot(logical(0) == 1) >> stopifnot(logical(0) == TRUE) >> stopifnot(logical(0) == FALSE) >> >> My understanding is that logical(0) is an empty set, so I would expect the >> above tests to fail. >> >> (I got bitten by this in a piece of code where "x" happened to be >> logical(0) and stopifnot didn't catch it) >> >> Thanks! >> Dario > -- > > David Winsemius > Alameda, CA, USA > > __ > 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. __ 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.
Re: [R] stopifnot with logical(0)
> On Dec 11, 2015, at 5:38 AM, Dario Beraldi 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" ) > > stopifnot(logical(0) == 1) > stopifnot(logical(0) == TRUE) > stopifnot(logical(0) == FALSE) > > My understanding is that logical(0) is an empty set, so I would expect the > above tests to fail. > > (I got bitten by this in a piece of code where "x" happened to be > logical(0) and stopifnot didn't catch it) > > Thanks! > Dario -- David Winsemius Alameda, CA, USA __ 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.
Re: [R] stopifnot with logical(0)
I think the inspection of the "stopifnot()" source code may help. > stopifnot function (...) { n <- length(ll <- list(...)) if (n == 0L) return(invisible()) mc <- match.call() for (i in 1L:n) if (!(is.logical(r <- ll[[i]]) && !anyNA(r) && all(r))) { ch <- deparse(mc[[i + 1]], width.cutoff = 60L) if (length(ch) > 1L) ch <- paste(ch[1L], "") stop(sprintf(ngettext(length(r), "%s is not TRUE", "%s are not all TRUE"), ch), call. = FALSE, domain = NA) } invisible() } The following code may help in understanding. (arg <- (logical(0) == 1)) (arg <- (logical(0) == TRUE)) (arg <- (logical(0) == FALSE)) n <- length(ll <- list(arg)) n if (n == 0L) return(invisible()) for (i in 1L:n) { print(is.logical(r <- ll[[i]])) print(!anyNA(r)) print(all(r)) if (! (is.logical(r <- ll[[i]]) && !anyNA(r) && all(r)) ) { print("stop") } } Executing such code: > (arg <- (logical(0) == 1)) logical(0) > (arg <- (logical(0) == TRUE)) logical(0) > (arg <- (logical(0) == FALSE)) logical(0) > > n <- length(ll <- list(arg)) > n [1] 1 > > if (n == 0L) + return(invisible()) > > for (i in 1L:n) { + print(is.logical(r <- ll[[i]])) + print(!anyNA(r)) + print(all(r)) + if (! (is.logical(r <- ll[[i]]) && !anyNA(r) && all(r)) ) { + print("stop") + } + } [1] TRUE [1] TRUE [1] TRUE > See also help(all) and what its "Note" states about all(logical(0)) and consider that: > is.logical(logical(0)) [1] TRUE -- GG [[alternative HTML version deleted]] __ 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.
Re: [R] stopifnot with logical(0)
The goal of the comparison operators is to obtain a logical value. Why compare logical values... you clearly already have that? stopifnot( logicalvariable ) and stopifnot( !logicalvariable ) are sensible, but not stopifnot( logicalvariable == TRUE ) or stopifnot( logicalvariable == FALSE ) That said, R lets you construct the department of redundancy department anyway, but you have to have a value to compare. logical(0) is the absence of a logical value, so there is nothing to compare, so the result has to also be the absence of a logical value (logical(0)). Somewhere, the test that lead to the existence of this empty logical vector had no data. That absence of data is what you need to test for. Or, at the very least, you need to verify that the length of your logical variable is greater than zero before checking its value. -- Sent from my phone. Please excuse my brevity. On December 11, 2015 5:38:47 AM PST, Dario Beraldi 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: > >stopifnot(logical(0) == 1) >stopifnot(logical(0) == TRUE) >stopifnot(logical(0) == FALSE) > >My understanding is that logical(0) is an empty set, so I would expect >the >above tests to fail. > >(I got bitten by this in a piece of code where "x" happened to be >logical(0) and stopifnot didn't catch it) > >Thanks! >Dario > > [[alternative HTML version deleted]] > >__ >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. [[alternative HTML version deleted]] __ 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.
Re: [R] stopifnot with logical(0)
The reason is probably that any(logical()) and any(!logical()) return FALSE (there are no TRUEs in logical(0)). Bill Dunlap TIBCO Software wdunlap tibco.com On Fri, Dec 11, 2015 at 5:38 AM, Dario Beraldi 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: > > stopifnot(logical(0) == 1) > stopifnot(logical(0) == TRUE) > stopifnot(logical(0) == FALSE) > > My understanding is that logical(0) is an empty set, so I would expect the > above tests to fail. > > (I got bitten by this in a piece of code where "x" happened to be > logical(0) and stopifnot didn't catch it) > > Thanks! > Dario > > [[alternative HTML version deleted]] > > __ > 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. __ 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.