【问题标题】:Comparing each element in two columns and set another column比较两列中的每个元素并设置另一列
【发布时间】:2017-07-27 12:47:59
【问题描述】:

我有一个包含两列(dep 和 label)的数据框(从文件中读取后)。我想根据匹配设置另一个具有 id 值的列(标记)。如果 'dep' 条目匹配 'labell' 条目,标记获取匹配的 'label' 的 'id'。对于不匹配,mark 获取它自己的 '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 中的循环很慢,只是举个例子,以下幼稚的 for/while 适用于小尺寸,但我的数据集很大。

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] 

【问题讨论】:

    标签: r


    【解决方案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
    

    更新:

    要确保您没有将 dep 与 0 或 -1 值匹配,您可以添加另一行。

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

    或 试试这个:

    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]
    

    【讨论】:

    • 工作就像一个魅力
    • 好的,所以在上面运行我的实际数据集(2581691 行)会导致以下错误。我应该在哪里指定=.EACHI? vecseq(f__, len__, if (allow.cartesian || notjoin || !anyDuplicated(f__, : Join 导致超过 2^31 行(内部 vecseq 达到物理限制) 中的错误。很可能是错误指定的连接。检查重复键i 中的每个值都一遍又一遍地加入 x 中的同一组。如果没问题,请尝试 by=.EACHI 为每个组运行 j 以避免大量分配。
    • 使用这个选项trace[trace[!dep %in% c(0,-1),.(id,dep=label)],mark:=as.character(i.id),on="dep",allow.cartesian=TRUE]
    • allow.cartesian=TRUE 会导致相同的错误。而使用以下选项运行没有错误。不确定,它会成功但最后几分钟不会出错 trace[trace[!dep %in% c(0,-1),.(id,dep=label)],mark:=as.character(i. id),on="dep",by=.EACHI]
    • @Saltaf 我又发现了一个想法。看看它是否有效...trace[trace[,.(id,dep=label)],on=.(id&lt;=id,dep),mark:=as.character(i.id),allow.cartesian=TRUE]
    猜你喜欢
    • 1970-01-01
    • 2019-01-19
    • 1970-01-01
    • 2019-12-07
    • 2020-07-04
    • 1970-01-01
    • 2022-11-23
    相关资源
    最近更新 更多