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

如何修正R中ggalluvial/ggsankey桑基图的id变量排序

问题描述

现有如下R数据集,使用ggsankey预处理后用ggalluvial绘制桑基图时,id节点的排序出现异常,显示为A1、A10、A2...的顺序,而非预期的A1到A10依次排列。

原始数据集代码

id <- c("A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "A10")
variation <- c("aaa1", "aaa1", "bbb1", "aaa2", "b1","a3", "a1", "b1", "a1", "b1" )
result <- c("Way1", "Way1", "Way2", "Way2", "Way3","Way1", "Way2", "Way3", "Way4", "Way1" )

data <- data.frame(id, variation, result)
head(data)

#     id variation result
# 1   A1      aaa1   Way1
# 2   A2      aaa1   Way1
# 3   A3      bbb1   Way2
# 4   A4      aaa2   Way2
# 5   A5        b1   Way3
# 6   A6        a3   Way1
# 7   A7        a1   Way2
# 8   A8        b1   Way3
# 9   A9        a1   Way4
# 10 A10        b1   Way1

桑基图预处理与绘制代码

library(ggsankey)

data_df <- data %>%
  make_long(id, variation, result)
head(data_df)
# A tibble: 6 × 4
# x         node  next_x    next_node
# <fct>     <chr> <fct>     <chr>    
#   1 id        A1    variation aaa1     
# 2 variation aaa1  result    Way1     
# 3 result    Way1  NA        NA       
# 4 id        A2    variation aaa1     
# 5 variation aaa1  result    Way1     
# 6 result    Way1  NA        NA  
library(ggalluvial)

ggplot(data_df, aes(x = x, next_x = next_x, node = node, next_node = next_node, fill = factor(node), label = node)) +
  geom_alluvial(flow.alpha = .6) +
  geom_alluvial_text(size = 3, color = "black") +
  scale_fill_viridis_d() +
  theme_alluvial(base_size = 18) +
  labs(x = NULL) +
  theme(legend.position = "none",
        plot.title = element_text(hjust = .5)) +
  ggtitle("")
解决方案

问题根源在于id是字符型变量,R默认按字典序排序("A10"的首字符"A"后是"1",比"A2"的"2"小,所以排在前面)。要解决这个问题,需要将id转换为有序因子,并指定正确的排序顺序,具体步骤如下:

  • 在原始数据中设置id的有序因子属性
    在创建data数据框前,先把id转换成有序因子,顺序按原始向量的顺序:

    id <- factor(c("A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "A10"), 
                 levels = c("A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "A10"),
                 ordered = TRUE)
    

    如果已经创建了data数据框,也可以直接修改列属性:

    data$id <- factor(data$id, levels = data$id, ordered = TRUE)
    
  • 重新生成桑基图数据集并绘图
    重新运行make_long预处理代码,再绘制桑基图,此时id节点会按A1到A10的顺序排列。

如果不想修改原始数据,也可以直接在预处理后的data_df中调整node列的因子顺序(需要列出所有节点的水平):

data_df$node <- factor(data_df$node, 
                       levels = c("A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "A10", 
                                  "aaa1", "bbb1", "aaa2", "b1", "a3", "a1", 
                                  "Way1", "Way2", "Way3", "Way4"),
                       ordered = TRUE)

内容的提问来源于stack exchange,提问作者choij

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 23:31:06