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

如何用data.table重现无共同列数据集的base R合并行为?

如何用data.table实现无共同列数据集的笛卡尔积合并?

我需要合并两个无共同列的data.table,最终得到行数为N1*N2的结果(N1、N2分别是两个数据集的行数)。

在base R中可以直接通过merge()实现:

A <- data.frame(id = 1:6, value = 19:24)
B <- data.frame(value2 = c(25, 25, 26, 26), value3 = 4:5)

A
#>   id value
#> 1  1    19
#> 2  2    20
#> 3  3    21
#> 4  4    22
#> 5  5    23
#> 6  6    24

B
#>   value2 value3
#> 1     25      4
#> 2     25      5
#> 3     26      4
#> 4     26      5

merge(A, B, all = TRUE)
#>    id value value2 value3
#> 1   1    19     25      4
#> 2   2    20     25      4
#> 3   3    21     25      4
#> 4   4    22     25      4
#> 5   5    23     25      4
#> 6   6    24     25      4
#> 7   1    19     25      5
#> 8   2    20     25      5
#> 9   3    21     25      5
#> 10  4    22     25      5
#> 11  5    23     25      5
#> 12  6    24     25      5
#> 13  1    19     26      4
#> 14  2    20     26      4
#> 15  3    21     26      4
#> 16  4    22     26      4
#> 17  5    23     26      4
#> 18  6    24     26      4
#> 19  1    19     26      5
#> 20  2    20     26      5
#> 21  3    21     26      5
#> 22  4    22     26      5
#> 23  5    23     26      5
#> 24  6    24     26      5

但改用data.table直接调用merge()会报错,因为data.table要求必须明确指定合并列:

library(data.table)

A <- data.table(id = 1:6, value = 19:24)
B <- data.table(value2 = c(25, 25, 26, 26), value3 = 4:5)

merge(A, B, all = TRUE)
#> Error in merge.data.table(A, B, all = TRUE): A non-empty vector of column names for `by` is required.

解决方案

可以通过以下几种方式用data.table实现相同的笛卡尔积合并效果:

方法1:添加临时共同列后使用merge()

给两个表添加一个完全相同的临时列,以此作为合并键,合并完成后再删除该临时列:

library(data.table)

A <- data.table(id = 1:6, value = 19:24)
B <- data.table(value2 = c(25, 25, 26, 26), value3 = 4:5)

# 添加临时键列
A[, temp_key := 1]
B[, temp_key := 1]

# 执行合并并删除临时列
result <- merge(A, B, by = "temp_key", all = TRUE)[, temp_key := NULL]

print(result)

方法2:利用索引生成笛卡尔积

通过生成两个表行索引的所有组合,再按索引提取对应行并拼接,这是更高效的方式:

library(data.table)

A <- data.table(id = 1:6, value = 19:24)
B <- data.table(value2 = c(25, 25, 26, 26), value3 = 4:5)

# 生成所有行索引的笛卡尔积组合
idx <- CJ(i = seq_len(nrow(A)), j = seq_len(nrow(B)), sorted = FALSE)

# 按索引提取行并拼接
result <- cbind(A[idx$i], B[idx$j])

print(result)

方法3:利用行复制拼接

通过重复行的方式直接生成笛卡尔积结构,再拼接第二个表的内容:

library(data.table)

A <- data.table(id = 1:6, value = 19:24)
B <- data.table(value2 = c(25, 25, 26, 26), value3 = 4:5)

# 重复A的行,次数等于B的行数
result <- A[rep(seq_len(.N), nrow(B))]
# 重复B的行,次数等于A的行数,添加到结果中
result[, c(names(B)) := B[rep(seq_len(.N), each = nrow(A))]]

print(result)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 18:50:26