tdsmith / aRrgh

A newcomer's (angry) guide to data types in R
Other
307 stars 14 forks source link

Testing for TRUE values #8

Closed cubranic closed 10 years ago

cubranic commented 10 years ago

If you want to test a value where you're not sure if it's a logical TRUE or FALSE only (such as in the if condition), use isTRUE(). It does the right thing even with NA, NULL, and vectors:

> isTRUE(NULL)
[1] FALSE
> isTRUE(NA)
[1] FALSE
> isTRUE(c(TRUE, FALSE, NA)
[1] FALSE
> isTRUE(c(TRUE, TRUE)
[1] FALSE

No need for identical(TRUE, as.logical(x)).

tdsmith commented 10 years ago

Hi, thanks for your comment. isTRUE(x) is implemented as identical(TRUE,x). This is a point of style but I think the more explicit syntax is much clearer.

The if condition allows more flexibility than simply testing identity to TRUE or FALSE:

> if(3) { print('foo') }
[1] "foo"
> if(0) { print('foo') }
> 

In that sense it behaves similarly to languages like C and Python. However, 3 is not identical to TRUE, so invoking as.logical is necessary to test for the truth value of an arbitrary not-necessarily-already-boolean value.

cubranic commented 10 years ago

Is the purpose of this project to help programmers understand R or just for your venting? The "identical" check is mentioned in the guide in this sentence: "If you need to test the truth value of some x that may sometimes be NA or have zero length, you can test the charming and ever-so-concise expression identical(TRUE, as.logical(x)), which will always evaluate to true or false." There is a more concise (an idiomatic) way to test with "isTRUE", so you're at the same time saying that using the longer check is bad because it's verbose and good because it's clear.

Furthermore, you forget dealing with vectors in the check:

> if (1:3) print('yes') else print('no')
[1] "yes"
Warning message:
In if (1:3) print("yes") else print("no") :
  the condition has length > 1 and only the first element will be used
> if (identical(TRUE, as.logical(1:3))) print('yes') else print('no')
[1] "no"

So invoking as.logical is not going to help you to test for the truth value of an "arbitrary not-necessarily-already-boolean value", only if it's already a scalar.

tdsmith commented 10 years ago

"Is the purpose of this project to help programmers understand R or just for your venting?"

The former only to the extent that the latter is achieved.

There is a more concise (an idiomatic) way to test with "isTRUE", so you're at the same time saying that using the longer check is bad because it's verbose and good because it's clear.

That accurately represents my opinion, yes. I intend to stick with the longer phrasing because I disagree that isTRUE is clear, particularly to someone new to R; there are (by my admittedly personal and subjective metric) less surprising things that isTRUE could mean and it does not mean any of them. But I'm still going to roll my eyes every time I type it out.

Furthermore, you forget dealing with vectors in the check

This is true and disappointing and deserves qualification; thank you for bringing it to my attention. I can't decide if I'm somewhat mollified or further frustrated by the warning that if gives you, which indicates that R doesn't think the truth value of vectors is meaningful at all, but I guess it's at least consistent with the handling of zero-length vectors. Issue #10.

cubranic commented 10 years ago

You should probably mention all and any in that context then.

On 2013-10-28, at 11:15 PM, tim smith wrote:

Furthermore, you forget dealing with vectors in the check

This is true and disappointing and deserves qualification; thank you for bringing it to my attention. I can't decide if I'm somewhat mollified or further frustrated by the warning that if gives you, which indicates that R doesn't think the truth value of vectors is meaningful at all, but I guess it's at least consistent with the handling of zero-length vectors. Issue #10.