【问题标题】:Join in data.table with multiple matches加入具有多个匹配项的 data.table
【发布时间】:2018-01-16 12:36:30
【问题描述】:

我之前发布了一个关于在 data.table 中连接列的问题,其中一列 (dep) 具有条目的依赖信息。所以条目 3 依赖于标签为“40”的记录。然后为“匹配”列分配条目所依赖的标签的 id 值。问题发布在这里:Comparing columns uptill certain index in R

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      
2:  2  45    40    
3:  3  40    43     
4:  4  47    45    
5:  5  0     47     
6:  6  45    42    
7:  7  43    48  
8:  8  42    45     
9:  9  45    52    
10: 10  45   67  

会导致

    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[.(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  4,8  
10: 10  45   67  4,8  

我并不关心记录这些依赖项的格式。使用 mult="all" 对早期解决方案进行轻微修改,

trace[, mark := trace[.(dep = dep, id = id), on=.(label = dep, id < id), mult="all", toString(x.id)]]

结果

 id dep label                                   mark
 1:  1  -1    99 NA, NA, 2, NA, NA, 4, 3, 6, 4, 8, 4, 8
 2:  2  45    40 NA, NA, 2, NA, NA, 4, 3, 6, 4, 8, 4, 8
 3:  3  40    43 NA, NA, 2, NA, NA, 4, 3, 6, 4, 8, 4, 8
 4:  4  47    45 NA, NA, 2, NA, NA, 4, 3, 6, 4, 8, 4, 8
 5:  5   0    47 NA, NA, 2, NA, NA, 4, 3, 6, 4, 8, 4, 8
 6:  6  45    42 NA, NA, 2, NA, NA, 4, 3, 6, 4, 8, 4, 8
 7:  7  43    48 NA, NA, 2, NA, NA, 4, 3, 6, 4, 8, 4, 8
 8:  8  42    45 NA, NA, 2, NA, NA, 4, 3, 6, 4, 8, 4, 8
 9:  9  45    52 NA, NA, 2, NA, NA, 4, 3, 6, 4, 8, 4, 8
10: 10  45    67 NA, NA, 2, NA, NA, 4, 3, 6, 4, 8, 4, 8

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    好的,稍微修改一下:

    trace[, mark := trace[.(dep = dep, id = id), on=.(label = dep, id < id), 
      if (all(is.na(x.id))) NA_character_ else toString(x.id), by=.EACHI]$V1 ]
    
    # if not found, use current id
    trace[is.na(mark), mark := as.character(id) ]
    

    它使用as.character(id),因为mark 现在是一个字符串变量。

    要查看by=.EACHI 的工作原理,请尝试自行运行此部分:

    trace[.(dep = dep, id = id), on=.(label = dep, id < id), 
      if (all(is.na(x.id))) NA_character_ else toString(x.id), by=.EACHI]
    

    评论。我预计这不会很好地扩展到更大的表。此外,该列不再匹配id 的类型,因此不能用于合并等。list-class 列也会有同样的问题:

    trace[, mark := trace[.(dep = dep, id = id), on=.(label = dep, id < id), 
      list(list(na.omit(x.id))), by=.EACHI]$V1 ]
    
    # if not found, use current id
    trace[lengths(mark) == 0L, mark := as.list(id)]
    

    【讨论】:

    • 它适用于正常的测试用例。但是对于实际的百万行记录——正如你提到的——不起作用。
    猜你喜欢
    • 2013-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-14
    • 1970-01-01
    相关资源
    最近更新 更多