如何在R中绘制仅以疾病为分区的circlize弦图?
解决仅显示疾病分区的弦图绘制问题
要实现仅以疾病为分区的弦图,核心是先将基因×疾病的原始矩阵转换为疾病×疾病的关联矩阵,再传入chordDiagram()函数。以下是具体步骤:
1. 加载所需工具包
library(circlize) library(tidyr) library(dplyr)
2. 转换原始数据为长格式
先筛选出有药物记录的基因-疾病对,便于后续构建疾病间关联:
# 将矩阵转为长格式,仅保留药物数>0的记录 df_long <- as.data.frame(df) %>% rownames_to_column("gene") %>% pivot_longer(cols = -gene, names_to = "disease", values_to = "drug_count") %>% filter(drug_count > 0)
3. 构建疾病间的关联权重矩阵
我们需要计算每对疾病之间,由共享基因带来的药物数量总和(可根据需求调整权重计算方式,比如用乘积替代求和):
# 生成每个基因对应的疾病两两组合 disease_pairs <- df_long %>% group_by(gene) %>% summarize(diseases = list(disease)) %>% filter(lengths(diseases) >= 2) %>% # 仅保留关联至少两种疾病的基因 mutate(pairs = map(diseases, ~ combn(.x, 2, simplify = FALSE))) %>% unnest(pairs) %>% mutate(disease1 = sapply(pairs, `[`, 1), disease2 = sapply(pairs, `[`, 2)) %>% select(-diseases, -pairs) # 计算每对疾病的总权重(此处用基因在两个疾病中的药物数之和累加) pair_weights <- disease_pairs %>% left_join(df_long, by = c("gene", "disease1" = "disease")) %>% rename(drug1 = drug_count) %>% left_join(df_long, by = c("gene", "disease2" = "disease")) %>% rename(drug2 = drug_count) %>% mutate(total = drug1 + drug2) %>% group_by(disease1, disease2) %>% summarize(weight = sum(total), .groups = "drop") # 构建对称的疾病关联矩阵 disease_list <- unique(df_long$disease) disease_matrix <- matrix(0, nrow = length(disease_list), ncol = length(disease_list), dimnames = list(disease_list, disease_list)) # 填充矩阵 for(i in 1:nrow(pair_weights)) { d1 <- pair_weights$disease1[i] d2 <- pair_weights$disease2[i] disease_matrix[d1, d2] <- pair_weights$weight[i] disease_matrix[d2, d1] <- pair_weights$weight[i] }
4. 绘制仅含疾病分区的弦图
传入疾病关联矩阵,设置仅显示疾病分区:
# 绘制弦图,仅保留网格轨道 chordDiagram(disease_matrix, annotationTrack = "grid", preAllocateTracks = list(track.height = 0.1)) # 添加疾病标签(优化显示方向) circos.trackPlotRegion(track.index = 1, panel.fun = function(x, y) { circos.text(CELL_META$xcenter, CELL_META$ylim[1], CELL_META$sector.index, facing = "clockwise", niceFacing = TRUE, adj = c(0, 0.5)) }, bg.border = NA)
关键说明
直接用原始的基因×疾病矩阵绘制时,chordDiagram()会将行(基因)和列(疾病)都视为独立分区,因此会同时显示两者。转换为疾病×疾病矩阵后,行和列都是疾病类别,最终弦图就只会保留疾病分区。
内容的提问来源于stack exchange,提问作者DN1
相关产品推荐
相关产品推荐

