如何在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
相关产品推荐
相关产品推荐

