我有一個大的數據集和查找表。我需要爲數據集中的每一行返回滿足條件的查找中行的最小值。R多個條件加入使用data.table
鑑於我的數據集的大小,我不願意通過交叉連接一起破解一個iffy解決方案,因爲這會創建數百萬條記錄。我希望有人可以提出一個解決方案(理想情況下)利用base r或data.table,因爲這些解決方案已經以有效的方式被使用。
例
A<-seq(1e4,9e4,1e4)
B<-seq(0,1e4,1e3)
dt1<-data.table(expand.grid(A,B),ID=1:nrow(expand.grid(A,B)))
setnames(dt1, c("Var1","Var2"),c("A","B"))
lookup<-data.table(minA=c(1e4,1e4,2e4,2e4,5e4),
maxA=c(2e4,3e4,7e4,6e4,9e4),
minB=rep(2e3,5),
Val=seq(.1,.5,.1))
# Sample Desired Value
A B ID Val
99: 90000 10000 99 0.5
在SQL中,我會接着寫沿着這將加入所有匹配的記錄從lookup
到dt1
並返回最小Val
的
SELECT ID, A, B, min(Val) as Val
FROM dt1
LEFT JOIN lookup on dt1.A>=lookup.minA
and dt1.A<=lookup.maxA
and dt1.B>=lookup.minB
GROUP BY ID, A, B
線的東西。
更新
我的解決方法到目前爲止是這樣的:
CJ.table<-function(X,Y) setkey(X[,c(k=1,.SD)],k)[Y[,c(k=1,.SD)],allow.cartesian=TRUE][,k:=NULL]
dt1.lookup<- CJ.table(dt1,lookup)[A>=minA & A<=maxA & B>=minB,
list(Val=Val[which.min(Val)]),
by=list(ID,A,B)]
dt1.lookup<-rbind.fill(dt1.lookup, dt1[!ID %in% dt1.lookup$ID])
這將檢索所有的記錄,並允許其他列從查找表中返回,如果我需要他們。它也有強制選擇最小Val的好處。
注意:使用'CJ'(在'data.table'包中實現)比'expand.grid'快。 – Arun
@阿倫這是偉大的建議!非常感謝您 –
請參閱我的編輯,對您現有的解決方案進行小調整。 –