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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 05:54:54