如何生成多组元素间共有元素的计数矩阵?
多向量所有组合的共有元素计数矩阵生成方案
需求说明
我需要识别多个向量间所有可能组合的共有元素,此前尝试的方法仅能获取两组间的共有元素,无法满足需求。现有10个元素数量各异的向量,它们之间可能存在共有元素或组内专属元素,需要生成类似维恩图计数结果的数据框/矩阵,其中矩阵行名与列名相同时,对应值为该组的专属元素数量。
模拟数据
# 生成模拟数据:10个元素数量不同的组 set.seed(753) grp_list <- lapply(1:10, function(i) { paste0("target_", sample(1:40, sample(20:34))) }) names(grp_list) <- paste0("grp_", 1:10)
解决方案代码
library(purrr) # 步骤1:生成所有非空组组合(从1个组到10个组的所有子集) all_combs <- map(1:length(grp_list), function(k) { combn(names(grp_list), k, simplify = FALSE) }) %>% unlist(recursive = FALSE) # 给每个组合命名(用点连接组名) comb_names <- sapply(all_combs, function(x) paste(x, collapse = ".")) # 步骤2:构建元素-组归属矩阵,记录每个元素属于哪些组 all_elements <- unique(unlist(grp_list)) element_group_mat <- sapply(grp_list, function(grp) all_elements %in% grp) # 步骤3:计算每个元素的专属组合(即该元素恰好属于哪些组的集合) element_exact_comb <- apply(element_group_mat, 1, function(row) { paste(names(grp_list)[row], collapse = ".") }) # 步骤4:统计每个专属组合的元素数量(维恩图各区域的计数) exact_counts <- table(element_exact_comb) # 补全所有组合的计数,未出现的组合计数为0 exact_counts_full <- setNames(as.numeric(exact_counts[comb_names]), comb_names) exact_counts_full[is.na(exact_counts_full)] <- 0 # 步骤5:构建目标矩阵 result_mat <- matrix(0, nrow = length(comb_names), ncol = length(comb_names), dimnames = list(comb_names, comb_names)) # 填充矩阵对角线:对应组合的专属元素数量 diag(result_mat) <- exact_counts_full # 填充非对角线单元格:计算行组合与列组合的交集元素数量 for (i in seq_along(comb_names)) { for (j in seq_along(comb_names)) { if (i != j) { # 提取行、列组合对应的组集合 row_groups <- strsplit(comb_names[i], "\\.")[[1]] col_groups <- strsplit(comb_names[j], "\\.")[[1]] # 需同时属于两组所有组的元素 required_groups <- unique(c(row_groups, col_groups)) # 筛选符合条件的元素并统计数量 valid_elements <- all_elements[apply(element_group_mat[, required_groups, drop = FALSE], 1, all)] result_mat[i, j] <- length(valid_elements) } } } # 查看示例片段结果 sample_rows <- c("grp1", "grp2", "grp3", "grp4", "grp1.grp4.grp5.grp8.grp10", "grp1.grp2.grp3.grp4.grp5.grp6.grp7.grp8.grp9.grp10") sample_cols <- c("grp1", "grp2", "grp3", "grp4", "grp1.grp4.grp5.grp8.grp10", "grp1.grp2.grp3.grp4.grp5.grp6.grp7.grp8.grp9.grp10") print(result_mat[sample_rows, sample_cols])
代码说明
- 组数据整理:将分散的组向量统一存入列表,便于批量操作。
- 组合生成:生成所有非空组子集组合,作为矩阵的行/列标识。
- 元素归属分析:通过矩阵记录每个元素的组归属,明确每个元素的专属组集合。
- 专属计数统计:统计维恩图各区域(即元素专属组集合)的元素数量,填充到矩阵对角线。
- 交集计数计算:对非对角线单元格,计算同时满足行、列组合所有组归属要求的元素数量。
内容的提问来源于stack exchange,提问作者Douglas
相关产品推荐
相关产品推荐

