Code
=c(1:10^6)
x=90000.43
your.numberwhich(abs(x-your.number)==min(abs(x-your.number)))
[1] 90000
September 24, 2015
A colleague came to my office the other day with an interesting question:
Is there a way in R to find the closest number to X in a list?
I knowing full well the power the power of R, I naturally said that surely there is such a function, but I have never used it. So I set out to find it because I am curious. It turns out there isn’t one off the shelf closest
function. There are however a few solutions out there which I have collected and are bellow. To top it off there is a comparison of how fast each solution is.
Same source as before.
From here. It requires data.table
renv was unable to query available packages from the following repositories:
- # http://packages.deltarho.org/src/contrib -----------------------------------
error downloading 'http://packages.deltarho.org/src/contrib/PACKAGES.rds' [curl: (22) The requested URL returned error: 404]
error downloading 'http://packages.deltarho.org/src/contrib/PACKAGES.gz' [curl: (22) The requested URL returned error: 404]
error downloading 'http://packages.deltarho.org/src/contrib/PACKAGES' [curl: (22) The requested URL returned error: 404]
The following package(s) will be installed:
- data.table [1.14.8]
These packages will be installed into "~/Documents/projects/datalyst/renv/library/R-4.3/x86_64-pc-linux-gnu".
# Installing packages --------------------------------------------------------
- Installing data.table ... OK [linked from cache]
Successfully installed 1 package in 5.8 milliseconds.
library(data.table)
dt = data.table(x, val = x) # you'll see why val is needed in a sec
setattr(dt, "sorted", "x") # let data.table know that w is sorted
setkey(dt, x) # sorts the data
# binary search and "roll" to the nearest neighbour
# In the final expression the val column will have the you're looking for.
dt[J(your.number), roll = "nearest"]
x val
1: 90000.43 90000
user system elapsed
0.006 0.000 0.006
user system elapsed
0.002 0.000 0.002
user system elapsed
0.051 0.000 0.016
To my surprise the base R functions perform pretty well, though in really large datasets data.table
is worth a punt.
@online{domingues2015,
author = {Domingues, António},
title = {Finding the Closest Element to a Number in a Vector},
date = {2015-09-24},
url = {https://amjdomingues.com/posts/2015-09-24-finding-closest-element-to-a-number-in-a-list/},
langid = {en}
}