比较列直到R中的某个索引

时间:2017-08-01 21:45:08

标签: r data.table

我想比较两列(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"]

知道如何完成这个

1 个答案:

答案 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前缀表示从哪个表中获取。