8
votes

In R, I am using Min and Max to find minimum and maximum values for a given vector.

This vector is a result of computation and filter and often times could be NULL or empty list.

In such case, we get warnings such as:

Warning message: In max(el) : no non-missing arguments to max; returning -Inf

If you do this inside a loop (or ply) for multiple inputs, you would start encountering big list of warnings

The default value of Inf is not suitable for my purposes and would like to instead have 0 or some other value to be returned.

Now, apart from every time checking if the input is valid with if..else conditions, is there any way I can stipulate the default return value for these Min, Max methods in case of empty inputs.

  • For example, if you use na.rm=TRUE then it would be difficult to pre-check the input if it would become empty after NA is removed.
  • Another case would be min(which()). checking return value of which() first and then supplying conditionally to min() is not really something I want.

Also, post-processing the Min, Max results to manually remove/replace Inf with my own values is not really efficient way.

So, is there any efficient way of asking R to return me my own custom default value from Min, Max for empty vectors, instead of +Inf and -Inf ??

The pre-processing with if..else checks and post-processing with Inf replacement are not so elegant.

If writing custom wrapper around Min, Max is the only way, how would you suggest write it without compromising on speed or elegance?

2
R is case sensitive. If you're going to reference functions make sure you don't change a lower case to an upper case.Dason
Do you really want to specify arbitrary custom value, or only suppress +Inf/-Inf/NaN? NA seems like a perfectly fine suppress value in all cases.smci

2 Answers

9
votes

Well, it may not be elegant, but this seems to work:

mymax <- function(...,def='hello world',na.rm=FALSE)
    if(!is.infinite(x<-suppressWarnings(max(...,na.rm=na.rm)))) x else def

mymax() # 'hello world'
mymax(def=2) # 2
mymax(c(),NULL,def=2) # 2

mymax(c(),NA) # NA
mymax(1,c(NA,3),na.rm=TRUE) # 1

And it's not slower...

require(microbenchmark)
test <- rnorm(1e5)
microbenchmark(
    max=max(test),
    mymax=mymax(test)
)

# Unit: milliseconds
#   expr      min       lq   median       uq      max neval
#    max 1.135445 1.141384 1.143814 1.162171 1.689940   100
#  mymax 1.119248 1.123297 1.147054 1.190517 1.660244   100
1
votes

There is a solution for this in the hablar package that solves that min/max returns Inf when given an empty vector. The function s converts an empty vector (NULL) to NA.

The problem

min(NULL)

[1] Inf
Warning message:
In min(NULL) : no non-missing arguments to min; returning Inf

Solution

library(hablar)

min(s(NULL))
[1] NA

disclaimer I am biased for this solution since I authored the package.