首页 文章

data.table:笛卡儿加入和无匹配

提问于
浏览
1

我想在R中使用神奇的data.table包进行笛卡尔(全外)连接 . 但是,我想要提到无法比较的行,即我的两个data.tables“left”和“right”看起来像

key | data_left
  1 |       aaa
  2 |       bbb
  3 |       ccc

key | data_right
  1 |        xxx
  2 |        yyy

使用键列“键”的交叉连接给了我

key | data_left | data_right
  1 |       aaa |        xxx
  2 |       bbb |        yyy

但是,完全没有匹配的行 3 | ccc . 添加选项 nomatch=0 (而不是 nomatch=NA )没有帮助 . 我希望data.table只用NA来填充剩余的列,所以我希望如此

key | data_left | data_right
  1 |       aaa |        xxx
  2 |       bbb |        yyy
  3 |       ccc |         NA

Any idea what I can do in order to get this to work?

代码示例:

library(data.table)
left = data.table(keyCol = c(1,2,3), data_left = c("aaa", "bbb", "ccc"))
right = data.table(keyCol = c(1,2), data_right = c("xxx", "yyy"))
setkey(left, keyCol)
setkey(right, keyCol)
res0 = left[right, allow.cartesian=TRUE, nomatch=NA]
resNA = left[right, allow.cartesian=TRUE, nomatch=0]

1 回答

  • 1

    假设每个 keyCol 值最多有一行,我会......

    # setup
    kc = "keyCol"
    DTs = list(left, right)
    
    # make main table with key col(s)
    DT = unique(rbindlist(lapply(DTs, `[`, j = ..kc)))
    
    # get non-key cols
    for (d in DTs){
      cols = setdiff(names(d), kc)
      DT[d, on=kc, (cols) := mget(sprintf("i.%s", cols)) ][]
    }
    
    # cleanup loop vars
    rm(d, cols)
    

    这适用于更一般的情况......

    • 更多关键字(在 kc 中)和

    • 具有非重叠列名称的表(在 DTs 中) .


    如果您希望将键列作为结果中的键,则代码会简化:

    # make main table with key col(s)
    DT = setkey(unique(rbindlist(lapply(DTs, `[`, j = ..kc))))
    
    # get non-key cols
    for (d in DTs){
      cols = setdiff(names(d), kc)
      DT[d, (cols) := mget(sprintf("i.%s", cols)) ][]
    }
    

相关问题