我有一个R data.table,其中包含一个id列和多个列,指定了一个有序的阈值级别和相应的值。我想要做的是查找每一行中大于或等于该id参数的第一个级别,并返回相应的值。
以下是一个示例数据集。
DT<-data.table(id=c("Obs1","Obs2"),
level.1=c(1,1),level.2=c(2,4),level.3=c(3,8),
val.1=c(10,10),val.2=c(20,30),val.3=c(30,50))
DT
id level.1 level.2 level.3 val.1 val.2 val.3
1: Obs1 1 2 3 10 20 30
2: Obs2 1 4 8 10 30 50
所以,如果查找参数为:
params<-list("Obs1"=2.5,"Obs2"=1)
返回的值应为:
c(30,10).
我希望级别和值的数量可以是任意的,但它们需要满足类似于示例的命名惯例。我可以通过几个步骤解决这个问题,但这种方法非常丑陋,而且可能计算效率不高。
level.names<-colnames(DT)[grep("level",colnames(DT))]
val.names<-colnames(DT)[grep("val",colnames(DT))]
setkey(DT,id)
idx<-DT[,grep(TRUE,lapply(.SD,function(y)((params[[id]] <= y))))[1],
.SDcols=level.names,by=id]
values<-ifelse(is.na(idx$V1),as.numeric(NA),DT[,get(val.names[idx[id,V1]]),by=id]$V1)
我之前使用data.frames更加干净地解决了这个问题,使用plyr::ddply和我可以在data.frame中使用变量名作为列的事实。(为了简洁起见,我不在此处包括该解决方案。)
欢迎任何改进建议。