如何基于宽度对R语言Chord Diagram的扇区进行排序?
如何在circlize中按扇区宽度自定义排序弦图扇区
嘿,这个需求完全可以实现!circlize包其实提供了直接控制扇区顺序的参数,核心就是手动指定扇区的顺时针排列顺序——默认情况下扇区会按数据出现顺序或字母排序,我们只需要先计算每个扇区的宽度(也就是对应节点的关联总和),再按照你的需求自定义排序规则即可。
具体步骤和代码示例
假设你的数据是类似这样的关联数据框(包含from和to列):
library(circlize) # 模拟你的关联数据 df <- data.frame( from = sample(c("N/A", "Dean", "Aaron", "Malcolm", "Jay", "Alice", "Bob"), 100, replace = TRUE), to = sample(c("N/A", "Dean", "Aaron", "Malcolm", "Jay", "Alice", "Bob"), 100, replace = TRUE) )
1. 计算每个扇区的宽度(关联总和)
首先我们需要统计每个名称对应的总关联次数,这就是扇区宽度的来源:
# 统计所有节点的出现次数(from和to列都要纳入计算) sector_sizes <- table(c(df$from, df$to)) # 转成数据框方便后续排序处理 sector_sizes_df <- as.data.frame(sector_sizes) colnames(sector_sizes_df) <- c("sector", "size")
2. 自定义扇区顺序
按照你的需求,下半部分扇区要以N/A为首,之后按宽度降序排列(Dean、Aaron、Malcolm……Jay)。我们可以拆分上半部分和下半部分的扇区,分别定义顺序:
# 定义你想要放在下半部分的扇区 target_lower_sectors <- c("N/A", "Dean", "Aaron", "Malcolm", "Jay") # 处理下半部分的顺序:N/A排第一,剩下的按宽度降序 lower_sectors_order <- c( "N/A", # 筛选下半部分除N/A外的扇区,按size降序提取名称 sector_sizes_df %>% filter(sector %in% setdiff(target_lower_sectors, "N/A")) %>% arrange(desc(size)) %>% pull(sector) ) # 处理上半部分的扇区:剩下的扇区也可以按宽度降序排列(你也可以自定义其他规则,比如字母序) upper_sectors <- setdiff(sector_sizes_df$sector, target_lower_sectors) upper_sectors_order <- sector_sizes_df %>% filter(sector %in% upper_sectors) %>% arrange(desc(size)) %>% pull(sector) # 合并成完整的扇区顺序:上半部分 + 下半部分(circlize默认顺时针从3点钟方向开始排列) custom_order <- c(upper_sectors_order, lower_sectors_order)
3. 按自定义顺序绘制弦图
最后调用chordDiagram()时,通过order参数传入我们定义好的顺序即可:
# 先清除之前的circlize布局(避免冲突) circos.clear() # 可选:调整起始角度,让上半部分和下半部分的划分更直观 # start.degree=90 表示从12点钟方向开始顺时针排列,这样前半部分扇区会在上半圆 circos.par(start.degree = 90) # 绘制弦图,指定自定义顺序 chordDiagram(df, order = custom_order)
关键说明
chordDiagram()的order参数是核心,它接受一个字符向量,严格按这个向量的顺序顺时针排列扇区。- 如果你的扇区宽度是手动指定的(不是从数据自动计算),只需要把指定的宽度数据替换上面的
sector_sizes_df即可,排序逻辑完全一致。 - 如果你只想调整下半部分的顺序,上半部分保持默认,只需要把上半部分的顺序换成默认排序(比如
sort(upper_sectors))就行。
内容的提问来源于stack exchange,提问作者superasiantomtom95
相关产品推荐
相关产品推荐

