77个用药变量交集可视化:UpSetR的替代方案问询
多变量药物使用交集的可视化替代方案
问题背景
我正在处理患者数据,包含约77个表示患者是否使用某类药物的二元变量(0=未使用,1=使用),希望可视化不同药物的患者交集情况。使用UpSetR时,16个变量以内可视化效果良好,但纳入全部77个变量后图表杂乱无法解读。
数据示例:
my_dataframe <- as.data.frame(matrix(sample(c(0, 1), 637599 * 77, replace = TRUE), ncol = 77)) colnames(my_dataframe) <- paste0("Ind_", 1:77) library(UpSetR) upset(my_dataframe, nsets = 77)
两种效果对比:
- 变量数≤16时:[清晰的UpSetR交集可视化图表]
- 77个变量时:[杂乱无法解读的UpSetR图表]
替代可视化方法
1. 优化UpSetR展示(先简化数据)
77个变量全展示必然过载,先筛选数据再用UpSetR:
- 保留使用频率前N的药物(比如取前20个)
- 只展示交集计数≥阈值的组合
- 按交集频率排序,隐藏极小交集
代码示例:
# 计算药物使用频率,取前20个高频药物 drug_freq <- colSums(my_dataframe) top_drugs <- names(sort(drug_freq, decreasing = TRUE)[1:20]) filtered_data <- my_dataframe[, top_drugs] # 展示前30个大交集,按频率排序 upset(filtered_data, nsets = 20, nintersects = 30, keep.order = TRUE, order.by = "freq")
2. 桑基图
适合展示多组变量的共现/流量关系,尤其适合将药物分组后展示交集。用networkD3包实现:
代码示例:
library(networkD3) library(dplyr) library(tidyr) # 将每行药物使用情况转为列表 my_dataframe$id <- 1:nrow(my_dataframe) drug_usage <- my_dataframe %>% pivot_longer(cols = starts_with("Ind_"), names_to = "drug", values_to = "used") %>% filter(used == 1) %>% group_by(id) %>% summarise(drugs = list(drug)) # 筛选使用2-3种药物的患者(避免节点过多) subset_drugs <- drug_usage[sapply(drug_usage$drugs, length) %in% 2:3, ] # 构建两两共现的桑基图数据 links <- data.frame() for (i in 1:nrow(subset_drugs)) { drugs <- subset_drugs$drugs[[i]] if (length(drugs) >= 2) { links <- rbind(links, data.frame(source = drugs[1], target = drugs[2], value = 1)) } } links <- links %>% count(source, target, name = "value") # 转换为桑基图所需格式 nodes <- data.frame(name = unique(c(links$source, links$target))) links$source <- match(links$source, nodes$name) - 1 links$target <- match(links$target, nodes$name) - 1 sankeyNetwork(Links = links, Nodes = nodes, Source = "source", Target = "target", Value = "value", NodeID = "name", fontSize = 12, nodeWidth = 30)
3. 两两交集热图
用热图展示任意两种药物的共现患者数,快速识别高频共现药物对。用pheatmap包:
代码示例:
library(pheatmap) # 计算两两药物共现矩阵(同时使用两种药物的患者数) cooccur_matrix <- t(my_dataframe) %*% my_dataframe diag(cooccur_matrix) <- NA # 隐藏单药物使用数,聚焦共现 # 绘制聚类热图 pheatmap(cooccur_matrix, cluster_rows = TRUE, cluster_cols = TRUE, na_col = "white", main = "药物两两共现患者数热图", fontsize_row = 8, fontsize_col = 8)
4. 马赛克图
适合展示分类变量的交叉分布,可用于药物分组后的交集展示(比如按药物类别分组)。用vcd包:
代码示例:
library(vcd) # 取前3个高频药物,转为因子变量 top3_drugs <- names(sort(colSums(my_dataframe), decreasing = TRUE)[1:3]) mosaic_data <- my_dataframe[, top3_drugs] %>% mutate(across(everything(), ~factor(., levels = c(0,1), labels = c("未使用", "使用")))) # 绘制马赛克图展示三种药物的交集分布 mosaic(~ Ind_1 + Ind_2 + Ind_3, data = mosaic_data, shade = TRUE, legend = TRUE, main = "三种药物使用情况的交集分布")
5. 交互式平行坐标图
展示患者个体的药物使用组合模式,支持交互筛选查看。用GGally和plotly:
代码示例:
library(GGally) library(plotly) # 取前10个高频药物的子集 top10_drugs <- names(sort(colSums(my_dataframe), decreasing = TRUE)[1:10]) subset_data <- my_dataframe[, top10_drugs] # 绘制交互式平行坐标图 p <- ggparcoord(subset_data, columns = 1:10, scale = "globalminmax") + theme_minimal() + labs(title = "患者药物使用组合平行坐标图") ggplotly(p)
6. 交互式UpSet替代工具
用ComplexUpset实现交互式UpSet图,支持悬停查看详情、筛选交集,变量稍多时也能理清。
代码示例:
library(ComplexUpset) library(ggplot2) # 取前20个高频药物 top20_drugs <- names(sort(colSums(my_dataframe), decreasing = TRUE)[1:20]) filtered_data <- my_dataframe[, top20_drugs] # 绘制交互式UpSet图 upset(filtered_data, intersect = colnames(filtered_data), base_annotations = list( 'Intersection size' = geom_bar(aes(fill = ..count..)) ), sort_sets = 'descending', sort_intersections = 'descending') + theme(axis.text.x = element_text(angle = 45, hjust = 1))
内容的提问来源于stack exchange,提问作者Usman YousafZai
相关产品推荐
相关产品推荐

