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

如何在R的ggplot循环生成的柱状图中添加非NA观测总数

问题:为循环生成的ggplot柱状图添加非NA观测总数

我正在处理包含250列的调查数据,数据示例如下:

q1 <- factor(c("yes","yes","no","yes",NA,"yes","no","yes"))
q2 <- factor(c("Albania","USA","Albania","Albania","UK",NA,"UK","Albania"))
q3 <- factor(c(0,1,0,0,1,1,0,0))
q4 <- factor(c(0,NA,NA,NA,1,NA,0,0))
q5 <- factor(c("Dont know","Prefer not to answer","Agree","Disagree",NA,"Agree","Agree",NA))
q6 <- factor(c(1,NA,3,5,800,NA,900,2))

data <- data.frame(q1,q2,q3,q4,q5,q6)

为了循环遍历所有列并生成答案分布的柱状图列表,我用了以下代码:

barplot_list <- lapply(names(data), function(variable) {
  ggplot(
    data = data,
    mapping = aes(.data[[variable]])
  ) +
    geom_bar(width = 0.6, fill = "#0096FF") +
    labs(x = variable, y = "response count") +
    geom_text(aes(label=..count..),stat='count',position=position_dodge(0.9),hjust=-0.1)+
    scale_fill_brewer(palette = "Set2") +
    theme_bw() +
    theme(panel.grid.major.y = element_blank()) +
    coord_flip()
})

现在想为每个柱状图添加排除NA值后的观测总数,可显示在图例、图表内或标题处。我尝试过geom_text(stat = "count",aes(label = after_stat(sum(count)))),但会在每个柱子顶部显示总数。请问如何修改代码,使每个图中显示“Total = N”(N为对应列排除NA后的观测总数)?


解决方案1:将总数添加到图表标题中

在循环内部先计算当前列的非NA观测数,再把总数拼接进标题文本,修改后的代码如下:

barplot_list <- lapply(names(data), function(variable) {
  # 计算当前列非NA的观测总数
  total_obs <- sum(!is.na(data[[variable]]))
  ggplot(
    data = data,
    mapping = aes(.data[[variable]])
  ) +
    geom_bar(width = 0.6, fill = "#0096FF") +
    labs(
      x = variable, 
      y = "response count",
      title = paste0(variable, " - Total = ", total_obs)  # 标题中嵌入总数
    ) +
    geom_text(aes(label=after_stat(count)), stat='count', position=position_dodge(0.9), hjust=-0.1)+
    scale_fill_brewer(palette = "Set2") +
    theme_bw() +
    theme(panel.grid.major.y = element_blank()) +
    coord_flip()
})

解决方案2:在图表角落添加总数文本

如果不想修改标题,可使用annotate()在图表固定位置(比如右上角)添加总数文本,代码如下:

barplot_list <- lapply(names(data), function(variable) {
  total_obs <- sum(!is.na(data[[variable]]))
  ggplot(
    data = data,
    mapping = aes(.data[[variable]])
  ) +
    geom_bar(width = 0.6, fill = "#0096FF") +
    labs(x = variable, y = "response count") +
    geom_text(aes(label=after_stat(count)), stat='count', position=position_dodge(0.9), hjust=-0.1)+
    # 在右上角添加总数文本
    annotate("text", x = Inf, y = Inf, label = paste0("Total = ", total_obs), 
             hjust = 1.1, vjust = 1.1, size = 4, color = "darkgray") +
    scale_fill_brewer(palette = "Set2") +
    theme_bw() +
    theme(panel.grid.major.y = element_blank()) +
    coord_flip()
})

关键说明:

  • 两种方法都是先在循环内计算total_obs <- sum(!is.na(data[[variable]])),确保每个图表获取对应列的非NA总数。
  • 把原代码中的..count..替换为after_stat(count),这是ggplot2 3.0+版本推荐的标准语法,兼容性更强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 11:31:05