如何分析样本中5-10个特征的重叠组合并实现类UpSet图分析?
实现思路与代码方案
一、核心逻辑
要解决“识别拥有5-10个相同特征的样本组”问题,核心是先提取每个样本的可用特征集合,再计算不同样本组合的特征交集大小,最后筛选符合条件的组合——这和UpSet图的核心逻辑(展示集合间的交集关系)完全匹配。
二、分步实现
1. 数据预处理:提取样本的可用特征
先把长格式数据转换为“样本-可用特征集合”的形式,方便后续计算交集:
library(dplyr) library(tidyr) # 提取每个样本的可用特征列表 sample_features <- dat %>% filter(state == 1) %>% group_by(sample) %>% summarise(available_features = list(feature), .groups = "drop")
2. 计算样本组合的特征交集(以两两组合为例)
生成所有可能的样本对,计算每对的共同特征数,筛选出交集大小在5-10之间的组合:
library(combinat) # 生成所有样本两两组合 sample_pairs <- combn(sample_features$sample, 2, simplify = FALSE) # 计算每对的共同特征数并筛选 valid_pairs <- lapply(sample_pairs, function(pair) { # 获取两个样本的可用特征 feats_a <- sample_features$available_features[sample_features$sample == pair[1]][[1]] feats_b <- sample_features$available_features[sample_features$sample == pair[2]][[1]] # 计算交集大小和具体特征 common_count <- length(intersect(feats_a, feats_b)) if (common_count >= 5 & common_count <= 10) { data.frame( sample_ids = paste(pair, collapse = " & "), shared_feature_count = common_count, shared_features = paste(intersect(feats_a, feats_b), collapse = ", ") ) } }) %>% bind_rows() # 查看结果 head(valid_pairs)
如果需要分析3个及以上样本的组合,只需修改combn的m参数(比如m=3),并调整交集计算逻辑为多集合的交集:
# 生成3样本组合 sample_triples <- combn(sample_features$sample, 3, simplify = FALSE) valid_triples <- lapply(sample_triples, function(triple) { # 获取三个样本的可用特征列表 feats_list <- lapply(triple, function(s) sample_features$available_features[sample_features$sample == s][[1]]) # 计算三个集合的交集 common_feats <- Reduce(intersect, feats_list) common_count <- length(common_feats) if (common_count >=5 & common_count <=10) { data.frame( sample_ids = paste(triple, collapse = " & "), shared_feature_count = common_count, shared_features = paste(common_feats, collapse = ", ") ) } }) %>% bind_rows()
3. UpSet图可视化
用UpSet图直观展示符合条件的特征交集与样本组的关系,推荐两种工具:
工具1:UpSetR包(经典UpSet图)
library(UpSetR) # 转换为样本×特征的二进制矩阵(1=特征可用,0=不可用) feature_matrix <- dat %>% pivot_wider(names_from = feature, values_from = state, values_fill = 0) %>% column_to_rownames("sample") # 绘制UpSet图,高亮交集大小5-10的组合 upset(feature_matrix, nintersects = NA, # 显示所有符合条件的交集 queries = list( list(query = intersects, params = list(5:10), color = "#2E86AB", active = TRUE) ), mainbar.y.label = "样本组数量", sets.x.label = "拥有该特征的样本数", text.scale = c(1.1, 1.1, 0.9, 0.9, 1.1, 0.9))
工具2:ggupset包(适配tidyverse)
library(ggupset) # 绘制基于ggplot2的UpSet图,筛选交集大小5-10 ggplot(sample_features, aes(x = available_features)) + geom_bar(fill = "#2E86AB") + scale_x_upset(intersection_size_range = c(5, 10), # 只显示交集大小5-10的组合 n_intersections = 15) + # 最多显示15个组合 labs(x = "特征交集组合", y = "样本组数量") + theme_bw() + theme(axis.text.x = element_text(angle = 45, hjust = 1))
三、注意事项
- 当样本量较大时(比如n>30),多样本组合的数量会指数级增长,建议优先分析两两组合,或通过特征频率筛选高频特征后再计算交集,提升效率。
- 如果只需要统计“拥有k个共同特征的样本组数量”,可以在计算后对
shared_feature_count分组汇总。
内容的提问来源于stack exchange,提问作者BHN
相关产品推荐
相关产品推荐

