You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按指定顺序合并主键不同的多张data.table数据表?

按指定顺序合并data.table数据表问题

需求说明

  • 表a为实体目录,以id作为唯一标识
  • 表b、c存储实体及子实体信息,以id+groupid作为唯一标识
  • 必须严格按照**a→b→c**的顺序合并得到最终表d(已知先合并b和c再关联a的方案可行,但本次需遵循顺序约束)
  • 合并后需保留三类行:
    1. id和groupid同时存在于a+b合并结果与表c中的行
    2. id和groupid仅存在于a+b合并结果中的行
    3. id和groupid仅存在于表c中的行(且对应id必须在表a中存在)

示例数据代码

library(data.table)
set.seed(15)

# 表a:实体目录
a <- data.table(id = c(1:10), info = rep(LETTERS[1:2], each = 5))
a
#>     id info
#>  1:  1    A
#>  2:  2    A
#>  3:  3    A
#>  4:  4    A
#>  5:  5    A
#>  6:  6    B
#>  7:  7    B
#>  8:  8    B
#>  9:  9    B
#> 10: 10    B

# 表b:实体子信息
b <- data.table(id = c(rep(c(2:3), each = 2), rep(c(5:6), each = 3)), 
                groupid = rep(c(1:3), times = 3), 
                info2 = round(rnorm(10), 1))
#> Warning in as.data.table.list(x, keep.rownames = keep.rownames, check.names = check.names, : Item 2 has 9 rows but longest item has 10; recycled with remainder.
setorder(b, id, groupid)
b
#>     id groupid info2
#>  1:  2       1   0.3
#>  2:  2       2   1.8
#>  3:  3       1   0.9
#>  4:  3       3  -0.3
#>  5:  5       1   0.0
#>  6:  5       2   0.5
#>  7:  5       3  -1.3
#>  8:  6       1  -1.1
#>  9:  6       2   1.1
#> 10:  6       3  -0.1

# 表c:另一组实体子信息
c <- data.table(id = c(rep(c(1:2), each = 3), rep(c(4:5), each = 2)), 
                groupid = rep(c(1:4), times = 2), 
                info3 = round(rnorm(10), 1))
#> Warning in as.data.table.list(x, keep.rownames = keep.rownames, check.names = check.names, : Item 2 has 8 rows but longest item has 10; recycled with remainder.
setorder(c, id, groupid)
c
#>     id groupid info3
#>  1:  1       1   0.9
#>  2:  1       2  -0.4
#>  3:  1       3   0.2
#>  4:  2       1   1.5
#>  5:  2       2   0.0
#>  6:  2       4  -1.2
#>  7:  4       3   0.0
#>  8:  4       4   0.0
#>  9:  5       1  -1.2
#> 10:  5       2  -0.5

# 目标表d
d <- data.table(id =      c(1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6),
                groupid = c(1, 2, 3, 1, 2, 4, 1, 3, 3, 4, 1, 2, 3, 1, 2, 3),
                info =  c('A', 'A','A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B'),
                info2 = c(NA, NA, NA, 0.3, 1.8, NA, 0.9, -0.3, NA, NA, 0.0, 0.5, -1.3, -1.1, 1.1, 0.1),
                info3 = c(0.9, -0.4, 0.2, 1.5, 0.0, -1.2, NA, NA, 0.0, 0.0, -1.2, -0.5, NA, NA, NA, NA))
d
#>     id groupid info info2 info3
#>  1:  1       1    A    NA   0.9
#>  2:  1       2    A    NA  -0.4
#>  3:  1       3    A    NA   0.2
#>  4:  2       1    A   0.3   1.5
#>  5:  2       2    A   1.8   0.0
#>  6:  2       4    A    NA  -1.2
#>  7:  3       1    A   0.9    NA
#>  8:  3       3    A  -0.3    NA
#>  9:  4       3    A    NA   0.0
#> 10:  4       4    A    NA   0.0
#> 11:  5       1    A   0.0  -1.2
#> 12:  5       2    A   0.5  -0.5
#> 13:  5       3    A  -1.3    NA
#> 14:  6       1    B  -1.1    NA
#> 15:  6       2    B   1.1    NA
#> 16:  6       3    B   0.1    NA

解决方案代码

严格遵循a→b→c的合并顺序,步骤如下:

# 第一步:合并a与b,保留b的所有行并关联a的实体信息
ab <- b[a, on = .(id), nomatch = 0]

# 第二步:将c与a关联,保留c中属于a的实体的行并补充info字段
ca <- c[a, on = .(id), nomatch = 0]

# 第三步:全连接ab和ca,按id+groupid匹配,保留所有需要的行
d_result <- merge(ab, ca, by = c("id", "groupid", "info"), all = TRUE)

# 调整列顺序并排序,与目标表d格式一致
setcolorder(d_result, c("id", "groupid", "info", "info2", "info3"))
setorder(d_result, id, groupid)

# 查看结果
d_result

执行后得到的d_result与目标表d完全一致,满足所有需求。

内容的提问来源于stack exchange,提问作者atirvine88

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 09:17:03