R data.table有序列查找

mjr*_*eed 3 r data.table

我有一个带有id列和多列的R data.table,指定有序的阈值级别和相应的值.我想要做的是查找第一级的每一行,该行大于或等于该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
Run Code Online (Sandbox Code Playgroud)

所以如果查找参数:

params<-list("Obs1"=2.5,"Obs2"=1) 
Run Code Online (Sandbox Code Playgroud)

返回的值应为:

c(30,10).
Run Code Online (Sandbox Code Playgroud)

我还希望级别和值的数量有些随意,尽管它们将满足类似于示例的命名约定

我可以使用几个步骤来解决这个问题,但它非常难看并且计算效率可能不高:

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)
Run Code Online (Sandbox Code Playgroud)

我之前使用plyr :: ddply更清晰地使用data.frames解决了这个问题,并且我可以在data.frame中使用变量名称这一事实.(为简洁起见,我不在此处包含该解决方案.)

欢迎提出任何改进建议.

Aru*_*run 5

我使用滚动连接如下所示:

DT_m = melt(DT, measure=patterns("^level", "^val"), value.name=c("level", "val"))
query = list(id=c("Obs1", "Obs2"), level=c(2.5, 1))
DT_m[query, val, on=c("id", "level"), roll=-Inf]
Run Code Online (Sandbox Code Playgroud)

roll=-Inf执行NOCB连接(后向观察向后进行).当通过(此处query)加入的值落入间隙时,下一个观察结果作为匹配行向后传送.例如,2.5介于2和之间4.因此匹配行4(下一次观察).相应的val30.

  • 谢谢!两种解决方案都有很大的改 了解熔体和轧制连接将是非常有益的. (2认同)