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.
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