如何在geom_flow()中基于变量大小而非层大小计算百分比
解决ggalluvial桑基图中geom_flow百分比计算异常问题(适配分面场景)
问题描述
使用ggalluvial的geom_flow()绘制包含3个及以上变量的桑基图时,中间列的流量百分比仅为预期值的一半。例如从V1到V2的A类流出百分比为26%,但V2中A类的流入百分比却显示13%。这是因为默认的prop统计量是按**层的总流量(流入+流出总和,比如200)**计算,而非当前变量分组的总样本量(比如100)。
解决方案
核心思路是基于当前x轴变量(即每个列对应的分组)的总样本量计算百分比,而非依赖stat="flow"默认的prop值。通过after_stat()筛选出当前分组的总样本数,再用流量的count除以该总数得到正确百分比,同时该方法天然适配分面场景(分面时会自动按子图分组计算总和)。
修改后的代码
library(ggplot2) library(ggalluvial) set.seed(123) df <- data.frame(id = rep(1:100, 3), value = sample(c("A", "B"), replace = TRUE, 300), variable = rep(c("V1", "V2", "V3"), each = 100), N = 1 ) ggplot(df, aes(x = variable, stratum = value, alluvium = id, y = N, fill = value)) + geom_lode() + geom_flow() + geom_stratum(alpha = 0) + geom_text(stat = "flow", aes( # 基于当前分组的总样本量计算百分比 label = scales::percent(after_stat(count / sum(count[flow == "from"])), accuracy = 1), hjust = after_stat(flow) == "to" ))
关键解释
sum(count[flow == "from"]):在每个x轴分组(V1/V2/V3)内,筛选出所有flow=="from"的流量count并求和,得到当前分组的总样本量(比如100)。- 不管是
flow=="from"(流出)还是flow=="to"(流入),都用当前分组的总样本量作为分母,这样流出和流入的百分比会匹配,且分面时每个子图会自动使用自身的组大小计算百分比,无需硬编码数值。
异常效果示例

内容的提问来源于stack exchange,提问作者Gilean0709
相关产品推荐
相关产品推荐

