How to catch integer(0)?

RError HandlingIntegerTry Catch

R Problem Overview


Let's say we have a statement that produces integer(0), e.g.

 a <- which(1:3 == 5)

What is the safest way of catching this?

R Solutions


Solution 1 - R

That is R's way of printing a zero length vector (an integer one), so you could test for a being of length 0:

R> length(a)
[1] 0

It might be worth rethinking the strategy you are using to identify which elements you want, but without further specific details it is difficult to suggest an alternative strategy.

Solution 2 - R

If it's specifically zero length integers, then you want something like

is.integer0 <- function(x)
{
  is.integer(x) && length(x) == 0L
}

Check it with:

is.integer0(integer(0)) #TRUE
is.integer0(0L)         #FALSE
is.integer0(numeric(0)) #FALSE

You can also use assertive for this.

library(assertive)
x <- integer(0)
assert_is_integer(x)
assert_is_empty(x)
x <- 0L
assert_is_integer(x)
assert_is_empty(x)
## Error: is_empty : x has length 1, not 0.
x <- numeric(0)
assert_is_integer(x)
assert_is_empty(x)
## Error: is_integer : x is not of class 'integer'; it has class 'numeric'.

Solution 3 - R

Maybe off-topic, but R features two nice, fast and empty-aware functions for reducing logical vectors -- any and all:

if(any(x=='dolphin')) stop("Told you, no mammals!")

Solution 4 - R

Inspired by Andrie's answer, you could use identical and avoid any attribute problems by using the fact that it is the empty set of that class of object and combine it with an element of that class:

attr(a, "foo") <- "bar"

identical(1L, c(a, 1L))
#> [1] TRUE

Or more generally:

is.empty <- function(x, mode = NULL){
    if (is.null(mode)) mode <- class(x)
    identical(vector(mode, 1), c(x, vector(class(x), 1)))
}

b <- numeric(0)

is.empty(a)
#> [1] TRUE
is.empty(a,"numeric")
#> [1] FALSE
is.empty(b)
#> [1] TRUE
is.empty(b,"integer")
#> [1] FALSE

Solution 5 - R

if ( length(a <- which(1:3 == 5) ) ) print(a)  else print("nothing returned for 'a'") 
#[1] "nothing returned for 'a'"

On second thought I think any is more beautiful than length(.):

 if ( any(a <- which(1:3 == 5) ) ) print(a)  else print("nothing returned for 'a'") 
 if ( any(a <- 1:3 == 5 ) ) print(a)  else print("nothing returned for 'a'") 

Solution 6 - R

You can easily catch integer(0) with function identical(x,y)

x = integer(0)
identical(x, integer(0))
[1] TRUE

foo = function(x){identical(x, integer(0))}
foo(x)
[1] TRUE

foo(0)
[1] FALSE

Solution 7 - R

another option is rlang::is_empty (useful if you're working in the tidyverse)

The rlang namespace does not seem to be attached when attaching the tidyverse via library(tidyverse) - in this case you use purrr::is_empty, which is just imported from the rlang package.

By the way, rlang::is_empty uses user Gavin's approach.

rlang::is_empty(which(1:3 == 5))
#> [1] TRUE

Solution 8 - R

isEmpty() is included in the S4Vectors base package. No need to load any other packages.

a <- which(1:3 == 5)
isEmpty(a)
# [1] TRUE

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRoman LuštrikView Question on Stackoverflow
Solution 1 - RGavin SimpsonView Answer on Stackoverflow
Solution 2 - RRichie CottonView Answer on Stackoverflow
Solution 3 - RmbqView Answer on Stackoverflow
Solution 4 - RJamesView Answer on Stackoverflow
Solution 5 - RIRTFMView Answer on Stackoverflow
Solution 6 - RE NordView Answer on Stackoverflow
Solution 7 - RtjeboView Answer on Stackoverflow
Solution 8 - RAlex Yahiaoui MartinezView Answer on Stackoverflow