我有一个大的数据集和查找表。我需要为数据集中的每一行返回满足条件的查找中行的最小值。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
@阿伦这是伟大的建议!非常感谢您 –
请参阅我的编辑,对您现有的解决方案进行小调整。 –