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

如何在R中使用setDT连接表并合并多匹配的id2值

问题描述

现有两个数据表table1和table2,数据定义如下:

library(data.table)
table1 <- data.frame(id1 = c(1324, 7822, 2324, 29, 9999, 1010),
                     class = c(1, 1, 1, 2, 2, 1),
                     type = c("A", "A", "A", "B", "C", "D"),
                     number = c(1, 2.5, 98, 100, 80, 50))
table2 <- data.frame(id2 = c(1992, 1987, 1998, 1998, 2000, 2000, 2000, 2010, 2012),
                     class = c(3, 3, 1, 1, 3, 1, 2, 5, 1),
                     type = c("B", "C", "D", "A", "D", "D", "C", "B", "A"),
                     min_number = c(0, 0, 34, 0, 20, 45, 5, 23, 1),
                     max_number = c(18, 18, 50, 100, 100, 100, 100, 9, 10))

数据表内容:

> table1
   id1 class type number
1 1324     1    A    1.0
2 7822     1    A    2.5
3 2324     1    A   98.0
4   29     2    B  100.0
5 9999     2    C   80.0
6 1010     1    D   50.0

> table2
   id2 class type min_number max_number
1 1992     3    B          0         18
2 1987     3    C          0         18
3 1998     1    D         34         50
4 1998     1    A          0        100
5 2000     3    D         20        100
6 2000     1    D         45        100
7 2000     2    C          5        100
8 2010     5    B         23          9
9 2012     1    A          1         10

需要基于class和type字段连接两个表,将table2中匹配的id2字段合并到table1中,存储为final_tab1_tab2。当前使用的代码仅保留了最后一个匹配的id2值:

tab1_tab2 <- setDT(table1)[setDT(table2), on = c("class", "type"), 
           id2 := id2]

输出结果:

> tab1_tab2
    id1 class type number  id2
1: 1324     1    A    1.0 2012
2: 7822     1    A    2.5 2012
3: 2324     1    A   98.0 2012
4:   29     2    B  100.0   NA
5: 9999     2    C   80.0 2000
6: 1010     1    D   50.0 2000

期望输出是将所有匹配的id2用;分隔,格式如下:

> final_tab1_tab2
    id1 class type number       id2
1: 1324     1    A    1.0 1998;2012
2: 7822     1    A    2.5 1998;2012
3: 2324     1    A   98.0 1998;2012
4:   29     2    B  100.0        NA
5: 9999     2    C   80.0      2000
6: 1010     1    D   50.0 1998;2000

要求高效处理数千行数据,避免使用for循环。

解决方案

利用data.table的分组聚合和左连接功能即可实现,全程基于向量化操作,无需循环:

  1. 先对table2按class和type分组,将每组的id2用;拼接成字符串:
table2_agg <- setDT(table2)[, .(id2_str = paste(id2, collapse = ";")), by = .(class, type)]
  1. 将聚合后的表与table1进行左连接,把拼接好的id2_str字段合并到原表:
final_tab1_tab2 <- setDT(table1)[table2_agg, on = c("class", "type"), id2 := id2_str]

执行后得到的结果完全符合期望:

> final_tab1_tab2
    id1 class type number       id2
1: 1324     1    A    1.0 1998;2012
2: 7822     1    A    2.5 1998;2012
3: 2324     1    A   98.0 1998;2012
4:   29     2    B  100.0        NA
5: 9999     2    C   80.0      2000
6: 1010     1    D   50.0 1998;2000

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 18:46:17