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

在R中找出三列中任意两列的共有元素并汇总的方法

解决R语言中找出任意两列共有元素并汇总的问题

没问题,我来帮你搞定这个需求!先明确下你的数据情况:genus_sub里的ID列是微生物分类单元名称,其他以GutREF开头的列是不同样本的存在标记(1表示该分类在对应样本中存在,0表示不存在)。我们要找出任意两个样本列之间共有的存在分类,并完成汇总。

方法一:基础R实现

这种方法不需要额外安装包,用基础R函数就能完成:

步骤1:提取每个样本中存在的分类列表

首先把每个样本里值为1的分类(即ID)提取出来,存成列表:

# 提取所有样本列的名称(排除ID列)
sample_cols <- setdiff(names(genus_sub), "ID")

# 遍历每个样本列,提取存在的分类ID
sample_taxa <- lapply(sample_cols, function(col) {
  genus_sub$ID[genus_sub[[col]] == 1]
})
names(sample_taxa) <- sample_cols

步骤2:生成所有两两样本的组合

用combn函数生成所有不重复的样本对:

# 生成两两样本的组合(返回列表格式)
sample_pairs <- combn(sample_cols, 2, simplify = FALSE)

步骤3:计算每对样本的共有分类并汇总

遍历每个样本对,计算交集,然后整理成汇总数据框:

# 计算每对的共有元素并生成汇总结果
summary_list <- lapply(sample_pairs, function(pair) {
  # 获取两个样本的共有分类
  shared_taxa <- intersect(sample_taxa[[pair[1]]], sample_taxa[[pair[2]]])
  # 整理成数据框行
  data.frame(
    样本1 = pair[1],
    样本2 = pair[2],
    共有分类数量 = length(shared_taxa),
    共有分类名称 = paste(shared_taxa, collapse = ", ")
  )
})

# 合并所有行成最终汇总数据框
final_summary <- do.call(rbind, summary_list)

运行后,final_summary就是你要的汇总结果,包含每对样本的名称、共有分类的数量和具体名称。

方法二:tidyverse风格实现

如果你习惯用tidyverse系列包(比如dplyr、tidyr),可以用更简洁的管道式代码:

library(tidyverse)

final_summary <- genus_sub %>%
  # 把宽格式转成长格式,方便处理
  pivot_longer(-ID, names_to = "样本", values_to = "是否存在") %>%
  # 只保留存在的分类
  filter(是否存在 == 1) %>%
  # 自连接,找到同一个分类出现在不同样本的情况
  full_join(., ., by = "ID") %>%
  # 过滤掉重复的样本对(比如避免同时出现A-B和B-A)
  filter(样本.x < 样本.y) %>%
  # 按样本对分组汇总
  group_by(样本.x, 样本.y) %>%
  summarise(
    共有分类数量 = n(),
    共有分类名称 = paste(ID, collapse = ", "),
    .groups = "drop"
  )

这个方法的结果和基础R版本完全一致,代码更直观,适合熟悉tidyverse的用户。

举个例子,你的测试数据里所有样本都存在Oscillospiraceae (B; Firm),所以每对样本的共有分类名称里都会包含这个分类。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:49:15