【问题标题】:Merge (full join) recursively one data.table with each group of another data.table递归地合并(完全连接)一个 data.table 与另一个 data.table 的每一组
【发布时间】:2017-04-25 09:54:53
【问题描述】:

我有 2 个数据表:

a.id <- c("a","a","a","b","b","c","c","c","c")
b.id <- c(1,2,3,4,5,1,3,4,5)
x <- seq(1:9)
dt1 <- data.table(a.id,b.id,x)

rp <- c("r","s")
t <- rep(rp, each=5)
b.id <- rep(1:5, 2)
y <- sample.int(50, 10)
dt2 <- data.table(t, b.id, y)

对于dt1 中的每个a.id,我想完全加入dt2 中的每个t,将它们逐列添加到dt1 中,并将t 的值赋予列名称.由于这是一个完全连接,dt1 中所有缺少的x(b.id) 都将添加到NA

这是所需的输出(对于 r 和 s,这些是随机值):

 a.id    b.id    x     r     s
 a       1       1     14    40
 a       2       2     42    25
 a       3       3     32    11
 a       4       NA    33    3
 a       5       NA    21    1
 b       1       NA    14    40
 b       2       NA    42    25
 b       3       NA    32    11
 b       4       4     33    3
 b       5       5     21    1
 c       1       6     14    40
 c       2       NA    42    25
 c       3       7     32    11
 c       4       8     33    3
 c       5       9     21    1

我尝试过类似的方法:

dt1[, merge(.SD, dt2, by = "b.id", all = TRUE), by = a.id]

但它不起作用。

感谢您对这个问题的帮助。 谢谢你的时间。

【问题讨论】:

  • 试试split 即..lapply(split(dt1, dt1$a.id), function(x) merge(x, dt2, by = "b.id", all = TRUE))
  • 如果您打算使用sample(),请使用set.seed
  • 感谢@akrun。这提供了一个快速的解决方案。但是,我们将 t 保留为 1 列,并获得 a.id 的 NA。但这不是一个大问题。

标签: r merge data.table


【解决方案1】:

尝试类似:

f<-dcast(dt2,b.id~t)
dt1[f[rep(1:nrow(f),uniqueN(dt1$a.id)),
    c(.SD,list(a.id=rep(unique(dt1$a.id),each=nrow(f))))],on=c("a.id","b.id")]
#    a.id b.id  x  r  s
# 1:    a    1  1 40 28
# 2:    a    2  2  4 17
# 3:    a    3  3 11 13
# 4:    a    4 NA 49 42
# 5:    a    5 NA 29 37
# 6:    b    1 NA 40 28
# 7:    b    2 NA  4 17
# 8:    b    3 NA 11 13
# 9:    b    4  4 49 42
#10:    b    5  5 29 37
#11:    c    1  6 40 28
#12:    c    2 NA  4 17
#13:    c    3  7 11 13
#14:    c    4  8 49 42
#15:    c    5  9 29 37

结果不同,因为没有设置 seed

【讨论】:

    【解决方案2】:

    使用交叉连接可以做到:

    dcast(dt2, b.id~t, value.var = "y")[
      dt1[CJ(a.id=a.id, b.id=b.id, unique=TRUE), on=.(a.id, b.id)], on="b.id"]
    

    如果不是b.id 的所有可能值都在dt1$b.id 中,那么CJ() 部分应该类似于
    CJ(a.id=a.id, b.id=dt2$b.id, unique=TRUE)
    这是另一个变体:

    dt1[dcast(dt2, b.id~t, value.var = "y")[
      CJ(a.id=dt1$a.id, b.id=dt2$b.id, unique=TRUE), on=.(b.id)], on=.(a.id, b.id)]
    #     a.id b.id  x  r  s
    #  1:    a    1  1 46 24
    #  2:    a    2  2 50 33
    #  3:    a    3  3 14  6
    #  4:    a    4 NA 40 28
    #  5:    a    5 NA 30 29
    #  6:    b    1 NA 46 24
    #  7:    b    2 NA 50 33
    #  8:    b    3 NA 14  6
    #  9:    b    4  4 40 28
    # 10:    b    5  5 30 29
    # 11:    c    1  6 46 24
    # 12:    c    2 NA 50 33
    # 13:    c    3  7 14  6
    # 14:    c    4  8 40 28
    # 15:    c    5  9 30 29
    

    数据:

    library("data.table")
    set.seed(42)
    dt1 <- data.table(a.id=rep(c("a", "b", "c"), c(3,2,4)), b.id=c(1:5,1,3,4,5), x=1:9)
    dt2 <- data.table(t=rep(c("r","s"), each=5), b.id=1:5, y=sample.int(50, 10))
    

    【讨论】:

      猜你喜欢
      • 2019-04-17
      • 1970-01-01
      • 2015-12-24
      • 1970-01-01
      • 2019-12-16
      • 2020-05-08
      • 2014-01-08
      • 1970-01-01
      • 2021-06-25
      相关资源
      最近更新 更多