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

如何在R中生成合计为100%的取整百分比数据标签?

解决ggplot2中取整百分比标签总和不为100%的问题

核心思路和你在Excel里的方法完全一致:先计算所有类别的原始百分比,对前n-1项直接取整,最后一项用100减去前面所有取整后百分比的总和,强制让最终百分比总和为100%。

步骤1:加载包并准备示例数据

library(ggplot2)
library(dplyr)

# 示例数据:分类+对应数值
df <- tibble(
  category = c("A", "B", "C", "D"),
  value = c(123, 456, 789, 321)
)

步骤2:处理百分比并修正取整误差

df_processed <- df %>%
  mutate(
    # 计算原始百分比(保留足够小数位)
    pct_raw = value / sum(value) * 100,
    # 前n-1项直接取整,最后一项用100减去前面取整值的总和
    pct_rounded = ifelse(row_number() != n(), 
                         round(pct_raw), 
                         100 - sum(round(pct_raw)[-n()]))
  ) %>%
  # 生成包含绝对值和修正后百分比的标签
  mutate(label = paste0(value, " (", pct_rounded, "%)"))

步骤3:绘制堆叠100%条形图

ggplot(df_processed, aes(x = "", y = value, fill = category)) +
  geom_col(position = "fill") +
  # 添加修正后的标签,居中显示
  geom_text(aes(label = label), 
            position = position_fill(vjust = 0.5)) +
  coord_flip() + # 转为横向条形图,不需要可删除
  scale_y_continuous(labels = scales::percent_format()) +
  theme_minimal() +
  labs(x = "", y = "")

步骤4:绘制饼图(仅需修改坐标系统)

ggplot(df_processed, aes(x = "", y = value, fill = category)) +
  geom_col(position = "fill") +
  geom_text(aes(label = label), 
            position = position_fill(vjust = 0.5)) +
  coord_polar("y", start = 0) + # 转为饼图坐标
  scale_y_continuous(labels = scales::percent_format()) +
  theme_minimal() +
  # 隐藏饼图不需要的轴线和网格
  theme(axis.text = element_blank(),
        axis.title = element_blank(),
        panel.grid = element_blank()) +
  labs(fill = "Category")

关键说明

  • row_number() != n():dplyr中用来判断当前行是否为数据框的最后一行
  • 100 - sum(round(pct_raw)[-n()]):通过减法强制最后一项的百分比补足到总和100,完全复刻Excel的逻辑
  • 若需要保留一位小数,把round()换成round(., 1),同时最后一项的计算改为100 - sum(round(pct_raw, 1)[-n()])即可

内容的提问来源于stack exchange,提问作者Felipe D.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 18:01:20