Home > Mobile >  How to tell R that max/min of empty vector is okay
How to tell R that max/min of empty vector is okay

Time:09-25

I'm computing the maximum of each of a collection of vectors, and some of these vectors are empty. For my purposes, max(some.empty.vector) returning -Inf is okay; it is expected, and valid for the further calculations I need to do.

However, I'm getting a warning message, "no non-missing arguments to max". How can I tell R that max(some.empty.vector) is not a problem, so there's no need for the warning? I don't want to just ignore the warning message, since there might be warnings coming from other functions, which I wouldn't want to lose track of.

I looked for other questions referring to this error message, and they all appear to be originating from taking the min or max of a vector which is empty unexpectedly, so the problem is the input data, which should not be empty. I'm in a different situation, I have some vectors which I know are empty, and they should be empty, so I can't suppress the warning by ensuring those vectors are nonempty.

CodePudding user response:

We could wrap with suppressWarnings

suppressWarnings(max(numeric(0), na.rm = TRUE))
[1] -Inf

Or another option is max_ from hablar which by default have ignore_na = TRUE. It will return NA if the length is 0 or NULL

library(hablar)
max_(numeric())
[1] NA
max_(NULL)
[1] NA

CodePudding user response:

You can define a new function, max, calling base::max with suppressWarnings wrapped around it.

max <- function(...) suppressWarnings(base::max(...))

max(numeric(0))
#[1] -Inf
max(NULL)
#[1] -Inf

And the other calls return the expected values.

max(1:10)
max(c(1:10, NA))
max(c(1:10, NA), na.rm = TRUE)
max(c("a", "b"))

Note:

Like GuedesBF says, the original function max will be masked by the new function below. You will no longer be calling base::max but .GlobalEnv$max or globalenv()$max:

globalenv()$max(NULL)
#[1] -Inf

If later you want the warning, then you must remember that you have a new function loaded.
A better option might be

max2 <- function(..., warnings = TRUE) {
  if(warnings){
    suppressWarnings(base::max(...))
  } else {
    base::max(...)
  }
}

max2(NULL)
max2(NULL, warnings = FALSE)

CodePudding user response:

The answers above are fine, but I would recommend not using a generic suppressWarnings(), but rather checking for the particular condition you want to be careful about, e.g.

my_max <- function(..., na.rm = FALSE) {
   L <- list(...)
   if (length(L) == 0 || 
        (na.rm && length(na.omit(unlist(L))) ==0)) return(-Inf)
   return(base::max(..., na.rm = na.rm))
}

my_max()  ## -Inf
my_max(NA, c(NA, NA))
my_max(NA, c(NA, NA), na.rm = TRUE)

To be honest I'm not sure there are any other warnings that max() could produce, but this is best practice.

It is, unfortunately, to detect and suppress a particular warning message in R (you can use tryCatch() to condition on the text of a particular warning, but this is deprecated because message texts might be changed in a different language/locale setting. You can set up your own warnings to have custom classes so that they are easier to detect (see Advanced R), but with base-R functions you're stuck with what you're given.

  • Related