2017-04-18 65 views
4

最接近的值我有兩個整數/ posixct載體:的R - 最快的方式找到在矢量

a <- c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) #has > 2 mil elements 
b <- c(4,6,10,16) # 200000 elements 

現在我的所得矢量c應該包含向量的每個元素B的最近的元件:

c <- c(4,4,4,4,4,6,6,...) 

我試着用apply和which.min(abs(ab)),但它非常慢。

有沒有更聰明的方法來解決這個問題?有沒有data.table解決方案?

+0

如果它整理就像在你的榜樣它只是一次通過更大的矢量,手動跟蹤b中最接近的元素,否則使用上面暗示的二進制搜索。 –

回答

1
library(data.table) 

a=data.table(Value=c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)) 

a[,merge:=Value] 

b=data.table(Value=c(4,6,10,16)) 

b[,merge:=Value] 

setkeyv(a,c('merge')) 

setkeyv(b,c('merge')) 

Merge_a_b=a[b,roll='nearest'] 
+2

歡迎來到交叉驗證。謝謝您的回答。你能通過解釋代碼來擴展你的答案嗎? – Ferdi

+0

在我們合併兩個數據表的數據表中,有一個叫做nearest的選項,它把數據表a中的所有元素放到數據表b中最近的元素上。結果數據表的大小將等於b的大小(該大小在括號內)。我需要像平常一樣進行合併的公用密鑰。 –

2

不太確定它如何表現與您的音量,但cut是相當快。

這個想法是在b的元素之間的中點剪切你的矢量a

請注意,我假設b中的元素嚴格增加!

像這樣:

a <- c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) #has > 2 mil elements 
b <- c(4,6,10,16) # 200000 elements 

cuts <- c(-Inf, b[-1]-diff(b)/2, Inf) 
# Will yield: c(-Inf, 5, 8, 13, Inf) 

cut(a, breaks=cuts, labels=b) 
# [1] 4 4 4 4 4 6 6 6 10 10 10 10 10 16 16 
# Levels: 4 6 10 16 

這甚至更快使用像findInterval較低級別的功能(再次,假定斷點非遞減)。

findInterval(a, cuts) 
[1] 1 1 1 1 2 2 2 3 3 3 3 3 4 4 4 

所以你當然可以這樣做:

index = findInterval(a, cuts) 
b[index] 
# [1] 4 4 4 4 6 6 6 10 10 10 10 10 16 16 16 

請注意,您可以選擇上發生了什麼是等距離的b元素通過傳遞相關參數cuta元素(或findInterval),請參閱他們的幫助頁面。

0

正如在this link呈現,你可以做兩種:

which(abs(x-your.number)==min(abs(x-your.number))) 

which.min(abs(x-your.number)) 

其中x是您的載體和your.number是價值