我想比较两列(dep和label)并在第三列(标记)中设置一个条目,只有在' dep'匹配标签'对于先前的索引值。例如,在以下示例中,' label = 40' (id = 2,dep = 45)但我们将标记设置为2,因为匹配标签(45)稍后存在(id = 4或8)。此外,如果有多个匹配,我们保留最近的匹配。例如,标签52(id 9)取决于45,所以选择id为8的最近匹配的id。另外,当dep< 1
时,我不想进行比较library(data.table)
trace <- data.table(id=1:10, dep=c(-1,45,40,47,0,45,43,42,45,45),
label=c(99,40,43,45,47,42,48,45,52,67), mark=rep("",10))
id dep label mark
1: 1 -1 99 1
2: 2 45 40 2
3: 3 40 43 2
4: 4 47 45 4
5: 5 0 47 5
6: 6 45 42 4
7: 7 43 48 3
8: 8 42 45 6
9: 9 45 52 8
10: 10 45 67 8
这个循环解决方案是
trace$mark <- trace$id
for (i in 1:length(trace$id)){
val <- trace$dep[i]
j <- 1
while(j<=i && val >1){
if(val==trace$label[j]){
trace$mark[i] <- trace$id[j]
}
j <-j +1
}
}
此前建议的以下解决方案设置所有值,无论它们是在当前索引之前还是之后发生。
trace[trace[dep>1,.(id,dep=label)],mark:=i.id,on="dep"]
知道如何完成这个
答案 0 :(得分:3)
这似乎有效:
# clean up OP's example
trace[, mark := NULL ]
# lookup label
trace[, mark :=
trace[.(dep = dep, id = id), on=.(label = dep, id < id), mult="last", x.id]
]
# if not found, use current id
trace[is.na(mark), mark := id ]
id dep label mark
1: 1 -1 99 1
2: 2 45 40 2
3: 3 40 43 2
4: 4 47 45 4
5: 5 0 47 5
6: 6 45 42 4
7: 7 43 48 3
8: 8 42 45 6
9: 9 45 52 8
10: 10 45 67 8
工作原理
x[i, on=, mult=, j]
是一个加入。 i
中查找x
的每一行。 i
的多行匹配x
行,mult=
确定会发生什么。x.*
中的x.id
前缀表示从哪个表中获取。