Search code examples
rradix

Match values to nearest, larger value in another list in R


There are several questions about how to find which number from a list is nearest to a given number. These answers, which mostly involve either which or which.min are two sided, so they return the number from a list which is closest to the given number, regardless of whether that number is larger or smaller than the given number.

I'd like to force the returned number to be larger than the given number, unless the given number itself appears on the list. This function works, but is there a simpler way?

viable_numbers <- c(15, Inf, 5, 10, 5)

picker <- function(x, viable_numbers) {
  if (x %in% viable_numbers) {
    return(x)
    
  } else {
    viable_numbers <- sort(unique(viable_numbers))
    return(viable_numbers[findInterval(x, viable_numbers) + 1])
  }
}
    
picker(x = 1, viable_numbers = viable_numbers)
[1] 5 # works
picker(x = 5, viable_numbers = viable_numbers)
[1] 5 # works
picker(x = 6, viable_numbers = viable_numbers)
[1] 10 # also works
picker(x = 20, viable_numbers = viable_numbers)
[1] Inf # still working

I prefer a base solution, but am open to a tidyverse answer as well.


Solution

  • You can take the minimum of the subset of the viable numbers that are equal to or greater than x:

    picker <-  function(x, viable_numbers) {
      min(viable_numbers[viable_numbers >= x])
    }
    
    picker(x = 1, viable_numbers = viable_numbers)
    [1] 5
    picker(x = 5, viable_numbers = viable_numbers)
    [1] 5 
    picker(x = 6, viable_numbers = viable_numbers)
    [1] 10 
    picker(x = 20, viable_numbers = viable_numbers)
    [1] Inf