Martin Maechler
2017-May-20 09:53 UTC
[R] [FORGED] Logical Operators' inconsistent Behavior
>>>>> Ramnik Bansal <ramnik.bansal at gmail.com> >>>>> on Sat, 20 May 2017 08:52:55 +0530 writes:> Taking this question further. > If I use a complex number or a numeric as an operand in logical > operations, to me it APPEARS that these two types are first coerced to > LOGICAL internally and then THIS logical output is further used as the > operand. > For eg. >> x <- 4+5i; c(x & F, x & T, x | F, x | T) > [1] FALSE TRUE TRUE TRUE > This output is consistent with >> x <- 4+5i; c(as.logical(x) & F, as.logical(x) & T, as.logical(x) | F, as.logical(x) | T) > [1] FALSE TRUE TRUE TRUE > This consistency makes me draw an on-the-surface conclusion that in > the case of logical operations if the operand is not of type 'logical' > it is first coerced into 'logical'. That conclusion is wrong as you show below. Rather, as the error message says, logical "operations are possible only for numeric, logical or complex types" Again: 1) Logical/Arithmetic operations "work" with "numeric-like" types, namely numeric, logical or complex, (and numeric = {integer, double}) ==> all other types give an error (the one you've cited twice) 2) For "numeric-like" types and *logical* operations (&, |, !; plus && and ||) the equivalent of as.logical() is applied before performing the Op. Seems pretty consistent ... and also according to the principle of "least surprise" (for me at least).
Duncan Murdoch
2017-May-20 10:18 UTC
[R] [FORGED] Logical Operators' inconsistent Behavior
On 20/05/2017 5:53 AM, Martin Maechler wrote:>>>>>> Ramnik Bansal <ramnik.bansal at gmail.com> >>>>>> on Sat, 20 May 2017 08:52:55 +0530 writes: > > > Taking this question further. > > If I use a complex number or a numeric as an operand in logical > > operations, to me it APPEARS that these two types are first coerced to > > LOGICAL internally and then THIS logical output is further used as the > > operand. > > > For eg. > >> x <- 4+5i; c(x & F, x & T, x | F, x | T) > > [1] FALSE TRUE TRUE TRUE > > > This output is consistent with > >> x <- 4+5i; c(as.logical(x) & F, as.logical(x) & T, as.logical(x) | F, as.logical(x) | T) > > [1] FALSE TRUE TRUE TRUE > > > This consistency makes me draw an on-the-surface conclusion that in > > the case of logical operations if the operand is not of type 'logical' > > it is first coerced into 'logical'. > > That conclusion is wrong as you show below. > Rather, as the error message says, > logical > "operations are possible only for numeric, logical or complex types" > > Again: > > 1) Logical/Arithmetic operations "work" with "numeric-like" types, namely > numeric, logical or complex, (and numeric = {integer, double}) > > ==> all other types give an error (the one you've cited twice) > > 2) For "numeric-like" types and *logical* operations (&, |, !; plus && and ||) > the equivalent of as.logical() is applied before performing the Op. > > Seems pretty consistent ... > and also according to the principle of "least surprise" (for me at least). >The surprise is that as.logical("TRUE") returns TRUE, whereas automatic coercion doesn't apply to character strings. I don't think we should change this, but it is an inconsistency. (We could perhaps mention it in the ?logical help page.) Duncan Murdoch Duncan Murdoch
Rolf Turner
2017-May-20 10:39 UTC
[R] [FORGED] Re: [FORGED] Logical Operators' inconsistent Behavior
On 20/05/17 22:18, Duncan Murdoch wrote:> On 20/05/2017 5:53 AM, Martin Maechler wrote: >>>>>>> Ramnik Bansal <ramnik.bansal at gmail.com> >>>>>>> on Sat, 20 May 2017 08:52:55 +0530 writes: >> >> > Taking this question further. >> > If I use a complex number or a numeric as an operand in logical >> > operations, to me it APPEARS that these two types are first >> coerced to >> > LOGICAL internally and then THIS logical output is further used >> as the >> > operand. >> >> > For eg. >> >> x <- 4+5i; c(x & F, x & T, x | F, x | T) >> > [1] FALSE TRUE TRUE TRUE >> >> > This output is consistent with >> >> x <- 4+5i; c(as.logical(x) & F, as.logical(x) & T, >> as.logical(x) | F, as.logical(x) | T) >> > [1] FALSE TRUE TRUE TRUE >> >> > This consistency makes me draw an on-the-surface conclusion that in >> > the case of logical operations if the operand is not of type >> 'logical' >> > it is first coerced into 'logical'. >> >> That conclusion is wrong as you show below. >> Rather, as the error message says, >> logical >> "operations are possible only for numeric, logical or complex types" >> >> Again: >> >> 1) Logical/Arithmetic operations "work" with "numeric-like" types, >> namely >> numeric, logical or complex, (and numeric = {integer, double}) >> >> ==> all other types give an error (the one you've cited twice) >> >> 2) For "numeric-like" types and *logical* operations (&, |, !; plus && >> and ||) >> the equivalent of as.logical() is applied before performing the Op. >> >> Seems pretty consistent ... >> and also according to the principle of "least surprise" (for me at >> least). >> > > The surprise is that as.logical("TRUE") returns TRUE, whereas automatic > coercion doesn't apply to character strings. I don't think we should > change this, but it is an inconsistency. (We could perhaps mention it > in the ?logical help page.)Actually it *is* mentioned. From ?logical:> Character strings c("T", "TRUE", "True", "true") are regarded as > true, c("F", "FALSE", "False", "false") as false, and all others as NA.cheers, Rolf -- Technical Editor ANZJS Department of Statistics University of Auckland Phone: +64-9-373-7599 ext. 88276