logical(0) in if statement
Asked Answered
R

4

26

This line:

which(!is.na(c(NA,NA,NA))) == 0

produces logical(0)

While this line

if(which(!is.na(c(NA,NA,NA))) == 0){print('TRUE')}

generates:

Error in if (which(!is.na(c(NA, NA, NA))) == 0) { : 
  argument is of length zero

Why there is an error? What is logical(0)

Robber answered 5/2, 2018 at 15:42 Comment(3)
A logical (i.e. boolean) vector of length 0. Since it has zero length, it doesn't have a truth value, so the if clause fails.Confessedly
You can do something like that: if(any(!is.na(c(NA,NA,NA))) == 0){print('TRUE')}Excavate
If you replace which with sum you will get the expected behavior, i.e. if(sum(!is.na(c(NA,NA,NA))) == 0){print('TRUE')}Kessler
C
29

logical(0) is a vector of base type logical with 0 length. You're getting this because your asking which elements of this vector equal 0:

> !is.na(c(NA, NA, NA))
[1] FALSE FALSE FALSE
> which(!is.na(c(NA, NA, NA))) == 0
logical(0)

In the next line, you're asking if that zero length vector logical(0) is equal to 0, which it isn't. You're getting an error because you can't compare a vector of 0 length with a scalar.

Instead you could check whether the length of that first vector is 0:

if(length(which(!is.na(c(NA,NA,NA)))) == 0){print('TRUE')}
Cyr answered 5/2, 2018 at 15:48 Comment(4)
"vector of class logical" should be "vector of mode logical" I think.Strep
@DavidTonhofer why do you think it should be mode instead of class?Cyr
Because "class" is the term for the object-oriented universes, but "mode" is (actually the old) R terminology for "base type". "base type" is better. From: Advanced R: Technically, the difference between base and OO objects is that OO objects have a “class” attribute butt also: You may have heard of mode() and storage.mode(). Do not use these functions: they exist only to provide type names that are compatible with S.Strep
OK thanks for the suggestion. I've changed "class" to "base type" as it seems the best choice of the three.Cyr
H
8

Calling which to check whether a vector of logicals is all false is a bad idea. which gives you a vector of indices for TRUE values. If there are none, that vector is length-0. A better idea is to make use of any.

> any(!is.na(c(NA,NA,NA)))
FALSE
Haematoxylon answered 5/2, 2018 at 16:22 Comment(0)
S
7

First off, logical(0) indicates that you have a vector that's supposed to contain boolean values, but the vector has zero length.

In your first approach, you do

!is.na(c(NA, NA, NA))
# FALSE, FALSE, FALSE

Using the which() on this vector, will produce an empty integer vector (integer(0)). Testing whether an empty set is equal to zero, will thus lead to an empty boolean vector.

In your second approach, you try to see whether the vector which(!is.na(c(NA,NA,NA))) == 0 is TRUE or FALSE. However, it is neither, because it is empty. The if-statement needs either a TRUE or a FALSE. That's why it gives you an error argument is of length zero

Sierra answered 5/2, 2018 at 15:48 Comment(0)
E
5

Simply use length() like so:

foo <- logical(0)

if(length(foo) == 0) { } # TRUE
if(length(foo) != 0) { } # FALSE
Epiglottis answered 18/1, 2020 at 4:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.