如何使用R的ggplot2包在堆叠的条形图中添加文本?

问题描述

我正在分析5分制的李克特量表,并尝试使用R的ggplot2可视化堆积的条形图。

可以在此链接中找到数据集-https://gofile.io/d/fKVZuL

我的数据集为.sav(SPSS)格式。

所以我正在按照以下代码读取此数据:

require("foreign")
d = read.spss(file.choose(),to.data.frame=TRUE)
attach(d)

现在要将5点李克特量表绘制成堆积的条形图,我使用了tidyverse软件包,其中包括ggplot2

require("tidyverse")
d %>% select(F1:F6) %>% na.omit %>% nrow
d %>% select(F1:F6) %>% na.omit -> f_items
f_items %>% gather(key = items,value = answer) %>% mutate(answer = factor(answer),items = factor(items)) -> data2

为了重新排列图例的键,我使用了以下代码

data2$answer = factor(data2$answer,levels = c("Strongly Agree","Agree","Neutral","disagree","Strongly disagree"))

然后,我使用以下代码创建了堆积条形图:

ggplot(data2,aes(x = items)) +
geom_bar(aes(fill = answer),position = "fill") +
coord_flip() +
scale_x_discrete(limits = rev(levels(data2$items)))+
scale_y_continuous(labels = scales::percent)+
scale_fill_brewer(palette="RdYlBu")-> p2
p2

这些代码产生以下数字:

enter image description here

现在,我想添加每个问题响应的百分比,如下图所示,但无法管理代码

enter image description here

如何添加这样的问题回答百分比?这将对我有很大的帮助。

-Shakil

解决方法

您可以尝试下一个代码。最好处理数据,使其具有@Axeman早期告诉您的标签和比例:

library(foreign)
library(tidyverse)
#Data
d = read.spss(file.choose(),to.data.frame=TRUE)
attach(d)
#Process
d %>% select(F1:F6) %>% na.omit %>% nrow
d %>% select(F1:F6) %>% na.omit -> f_items
f_items %>% gather(key = items,value = answer) %>% mutate(answer = factor(answer),items = factor(items)) -> data2
#Assign factor
data2$answer = factor(data2$answer,levels = c("Strongly Agree","Agree","Neutral","Disagree","Strongly Disagree"))
#Some code for proportions and labels
data2 %>% group_by(items,answer) %>% summarise(freq=n()) %>% ungroup() %>%
  group_by(items) %>% mutate(total = sum(freq),prop = freq/total) -> labdf
labdf %>% ungroup() -> labdf
#Create label
labdf$Label <- ifelse(labdf$prop<0.06,NA,paste0(100*round(labdf$prop,3),'%'))
#Plot
ggplot(labdf,aes(x = items,y = prop,group=answer))+
  geom_bar(stat='identity',aes(fill = answer),position = 'fill')+
  geom_text(aes(label = Label),position = position_fill(vjust = 0.5),size=3)+
  coord_flip() +
  scale_x_discrete(limits = rev(levels(data2$items)))+
  scale_y_continuous(labels = scales::percent)+
  scale_fill_brewer(palette="RdYlBu")-> p2
p2

输出:

enter image description here

有些比例太短,标签可能会覆盖其他比例。这就是为什么您可以修改labdf$Label <- ifelse(labdf$prop<0.06,'%'))以确定保留哪些标签的原因。