首页 > 解决方案 > 如何在具有多个键的数据表中进行完全外部联接?

问题描述

对于如何使用[]数据表的语法进行外连接有现有的答案,但它们没有解决如何使用多个键进行外连接。

这些是我的数据集

    A <- data.table(key_a=rep(1:2, 3), key_b = rep(c("blue", "orange", "purple"), 2), 
                    id=rep(11:13), chair = c("green", "red", "green", rep("red", 3)))[, 
            .(join_key = paste0(key_a, key_b), key_a, key_b, id, chair)] 
    B <- A[, .(key_a = key_a + 1, key_b, id, chair)][,
             .(join_key = paste0(key_a, key_b), key_a, key_b, id, chair)]    

我想创建这个输出

        key_a     key_b     chair      id   i.id 
    1:      1      blue     green      NA     11 
    2:      1    orange       red      NA     12 
    3:      1    purple     green      NA     13 
    4:      2      blue     green      11     NA 
    5:      2      blue       red      NA     11 
    5:      2    orange       red      12     12 
    6:      2    purple       red      NA     13 
    7:      2      blue     green      13     NA    
    7:      3      blue       red      11     NA     
    8:      3    orange       red      12     NA     
    9:      3    purple       red      13     NA      

我尝试用这段代码解决它

    unique_keys <- c(A[,join_key], B[,join_key])
    Aprime <- A[.(unique_keys), on= .(join_key)]
    setkey(Aprime, key_a, key_b, join_key, chair)
    
    B[Aprime, on = .(key_a), allow.cartesian = TRUE]

我想使用[]语法,因为我想在不创建新对象的情况下对 A 的引用进行更改

标签: rdata.table

解决方案


您可以查看 s方法getAnywhere('merge.data.table')的源代码- 该方法是使用. 按照案例的逻辑查看使用时会发生什么:mergedata.table[all=TRUEmerge

outer_join = merge(B, A, all=TRUE, by=c('key_a', 'key_b'))

基本上这会做:

  1. B[A, nomatch=NA]离开B加入A
  2. B[!A]反连接BA(找到B现在在 中找到的行A,左连接中会丢失)
  3. rbind1. 和 2. 的输出以完成外连接

最后一步是什么使得这不可能像通常推荐的连接和更新那样执行“按引用” data.table- 我们可以通过引用更新现有行新/现有列data.table但我们不能添加新行引用。


推荐阅读