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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 22:25:10