2017-07-27 111 views
0

我有两列(dep和label)的数据框(在fread之后)。我想设置另一个列(标记)与id值取决于匹配。如果'dep'条目与'lablel'条目匹配,则标记获得匹配'label'的'id'。如果不匹配,请标记自己的'id'的值。目前,我有解决循环的工作,但我知道应该有一个很好的方法来完成R的细节。比较两列中的每个元素并设置另一列

trace <- data.table(id=seq(1:7),dep=c(-1,45,40,47,0,45,43), 
label=c(99,40,43,45,47,42,48), mark=rep("",7)) 
    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 

我知道环路中的R慢,只是给例如以下天真了/而适用于小型尺寸,但我的数据集是巨大的。

trace$mark <- trace$id 
for (i in 1:length(trace$id)){ 
val <- trace$dep[i] 
j <- 1 
while(j<=i && val !=-1 && val!=0){ // don't compare if val is -1/0 

    if(val==trace$label[j]){ 
      trace$mark[i] <- trace$id[j] 
        } 
j <-j +1 
} 
} 

我也试过使用下面的方法,但它只适用于有单个匹配。

match <- which(trace$dep %in% trace$label) 
match_to <- which(trace$label %in% trace$dep) 
trace$mark[match] <- trace$mark[match_to] 

回答

1

该解决方案可以帮助:

trace[trace[,.(id,dep=label)],mark:=as.character(i.id),on="dep"] 
trace[mark=="",mark:=as.character(id)] 
# id dep label mark 
# 1: 1 -1 99 1 
# 2: 2 45 40 4 
# 3: 3 -1 43 3 
# 4: 4 47 45 5 
# 5: 5 -1 47 5 
# 6: 6 45 42 4 
# 7: 7 43 48 3 

更新:

要确保你不与0-1值匹配dep你可以另起一行。

trace[dep %in% c(0,-1), mark:= as.character(id)] 

OR 试试这个:

trace[trace[!dep %in% c(0,-1),.(id,dep=label)],mark:=as.character(i.id),on="dep"] 
trace[mark=="",mark:=as.character(id)] 

奏效

trace[trace[,.(id,dep=label)],on=.(id<=id,dep),mark:=as.char‌​acter(i.id),allow.ca‌​rtesian=TRUE] 
+0

@Saltaf看我的更新解决方案。 –

+0

像魅力一样工作 – Saltaf

+0

好的,所以在上面运行我的实际数据集(2581691行)会导致以下错误。我应该在哪里指定= .EACHI?如果(allow.cartesian || notjoin ||!anyDuplicated(f__,: )加入结果超过2^31行(内部vecseq达到物理限制)。很可能是指定的连接错误。检查重复的键值,每个键值在x中一次又一次地加入到同一个组中,如果没有问题,可以试试= .EACHI为每个组运行j以避免大的分配 – Saltaf

相关问题