首页 > 解决方案 > 在 R 的 data.table 包中,当某些情况发生时,是否可以通过不同的键加入?

问题描述

我有两个表通过 2 个键具有多对多关系。

其中一张表包含NA其中一个键中的值。这些NA值通常出现在另一个表只有该键的一个现有值时。

当值不是时,我想通过两个键加入,NA当第二个键是时,我想通过一个键加入NA

目前我有一个两步的方法,但我想知道是否有更好的方法来做到这一点。

这是我可重现的示例:

library(data.table)
    set.seed(14)
    dt1 <-
        data.table(
            key1 = c("A", "A", "B", "B", "C"),
            key2 = c("A-opt1", "A-opt2", "B-opt1", "B-opt1", "C-opt1"),
            measure_1 = rpois(5, 2)
        )

    print(dt1)
#>    key1   key2 measure_1
#> 1:    A A-opt1         1
#> 2:    A A-opt2         2
#> 3:    B B-opt1         5
#> 4:    B B-opt1         2
#> 5:    C C-opt1         5

    dt2 <-
        data.table(
            id = c(1:5),
            key1 = c("A", "A", "A", "B", "C"),
            key2 = c("A-opt1", "A-opt2", "A-opt2", NA, NA),
            measure_2 = rnorm(5)
        )

    print(dt2)
#>    id key1   key2  measure_2
#> 1:  1    A A-opt1  0.0287647
#> 2:  2    A A-opt2 -0.1803785
#> 3:  3    A A-opt2 -0.3011443
#> 4:  4    B   <NA> -0.9790001
#> 5:  5    C   <NA>  1.0416423

    # This is my current two step approach

    result <- dt1[dt2, on = .(key1 == key1, key2 == key2), nomatch = 0L]
    result <-
        rbind(result, dt1[dt2[is.na(key2)], on = .(key1 == key1), nomatch = 0L][, .SD, .SDcols = names(result)])

    print(result)
#>    key1   key2 measure_1 id  measure_2
#> 1:    A A-opt1         1  1  0.0287647
#> 2:    A A-opt2         2  2 -0.1803785
#> 3:    A A-opt2         2  3 -0.3011443
#> 4:    B B-opt1         5  4 -0.9790001
#> 5:    B B-opt1         2  4 -0.9790001
#> 6:    C C-opt1         5  5  1.0416423

reprex 包(v0.3.0)于 2019 年 11 月 13 日创建

标签: rdata.table

解决方案


我个人会这样做:

rbind(
  merge(dt1, dt2[!is.na(key2)], by=c('key1', 'key2')),
  merge(dt1, dt2[is.na(key2)][,key2:=NULL], by='key1')
)

我认为它比您当前的方法更具可读性,但仍然包括这两个步骤,仅仅是因为您有两个不同的加入条件。


推荐阅读