R语言中识别矩阵相同行并对行索引分组的惯用方法
R语言识别矩阵重复行并分组的惯用方案
基础R实现(无额外依赖)
这是最通用的原生R写法,适合中小规模数据:
# 示例矩阵 mat <- matrix(c(2,5,5,3,4,6,2,5,4,6,4,6), ncol=2, byrow=T) # 生成每行唯一标识,按首次出现顺序生成分组ID group_id <- as.integer(factor(interaction(mat[,1], mat[,2], sep = "|"), levels = unique(interaction(mat[,1], mat[,2], sep = "|")))) # 输出形式1:行索引+分组ID的两列矩阵 groups <- cbind(seq_len(nrow(mat)), group_id) colnames(groups) <- c("行索引", "分组ID") print(groups) # 输出形式2:按分组拆分的行索引列表 group_list <- split(seq_len(nrow(mat)), group_id) print(group_list)
运行结果完全符合需求:
行索引 分组ID [1,] 1 1 [2,] 2 2 [3,] 3 3 [4,] 4 1 [5,] 5 3 [6,] 6 3 $`1` [1] 1 4 $`2` [1] 2 $`3` [1] 3 5 6
高性能实现(适合百万/千万级大规模数据)
对于你提供的1000万行级别的测试数据,推荐使用data.table实现,性能是基础R的5~10倍,内存占用更低,是工业级数据处理的惯用方案:
library(data.table) # 1000万行测试数据构造 set.seed(123) n <- 10000000 mat <- matrix(sample.int(10, 2*n, replace = T), ncol=2) # 转换为data.table后按两行内容分组生成ID dt <- as.data.table(mat) dt[, group_id := .GRP, by = .(V1, V2)] # 两种输出形式 groups <- as.matrix(dt[, .(行索引 = .I, 分组ID = group_id)]) group_list <- split(dt$.I, dt$group_id)
最佳实践建议
- 万行以下的小数据:优先用基础R方案,无需引入额外依赖,代码简洁易读
- 十万行以上的中大规模数据:优先用
data.table方案,性能优势非常明显 - 如果后续还要做分组聚合、过滤等操作,直接保留
data.table结构即可,无需转成矩阵或列表,后续操作效率更高 - 如果你习惯使用tidyverse生态,也可以用
dplyr::group_by(V1, V2) %>% dplyr::mutate(group_id = dplyr::cur_group_id())实现,语法更统一,但性能略低于data.table
内容的提问来源于stack exchange,提问作者Szabolcs
相关产品推荐
相关产品推荐

