将标签添加到百分比堆叠条形图 ggplot2

Jea*_*lur 5 plot r bar-chart ggplot2 dataframe

我是 ggplot 新手,希望为我正在为其进行可视化的数据集获得一些帮助。

这是我当前的代码:

#create plot
plot <- ggplot(newDoto, aes(y = pid3lean, weight = weight, fill = factor(Q29_1String, levels = c("Strongly disagree","Somewhat disagree", "Neither agree nor disagree", "Somewhat agree", "Strongly agree")))) + geom_bar(position = "fill", width = .732) 
#fix colors
plot <- plot + scale_fill_manual(values = c("Strongly disagree" = "#7D0000", "Somewhat disagree" = "#D70000","Neither agree nor disagree" = "#C0BEB8", "Somewhat agree" = "#008DCA", "Strongly agree" = "#00405B")) 
#fix grid
plot <- plot + guides(fill=guide_legend(title="29")) + theme_bw() + theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank()) + theme(panel.border = element_blank()) + theme(axis.ticks = element_blank()) + theme(axis.title.y=element_blank()) + theme(axis.title.x=element_blank()) + theme(axis.text.x=element_blank()) + theme(text=element_text(size=19,  family="serif")) + theme(axis.text.y = element_text(color="black")) + theme(legend.position = "top") + theme(legend.text=element_text(size=12)) 
#plot graph
plot
Run Code Online (Sandbox Code Playgroud)

这将创建这个条形图: 在此输入图像描述

现在我遇到的问题是尝试在这些栏上添加百分比标签。我想添加显示每个段的百分比的文本,居中并以白色字母显示。

不幸的是,我在添加 geom_text 时遇到了一些麻烦,因为它经常给我带来错误,因为我没有 x 变量,而且我不知道如何修复它,因为我使用 fill 的方式与其他方式相比有点特殊我见过用 x 和 y 变量完成它的方法。考虑到填充是每种类型响应的百分比(级别中显示的不同响应类型),我真的不知道我什至会为 x 变量添加什么。

任何帮助,将不胜感激!如果这很重要,很乐意回答有关数据集的任何问题。

这是两个相关列的示例(没有使用 head,因为该数据集中有很多变量)。基本上,它们显示受访者属于哪一方,以及他们是否强烈同意、有些同意等。

数据样本

这是两个变量的 dput 输出:

structure(list(pid3lean = structure(c("Democrats", "Democrats", 
"Democrats", "Democrats", "Independents", "Democrats", "Republicans", 
"Independents", "Republicans", "Democrats", "Democrats", "Independents", 
"Democrats", "Republicans", "Democrats", "Democrats", "Democrats", 
"Democrats", "Democrats", "Republicans"), label = "pid3lean", format.spss = "A13", display_width = 15L), 
    Q29_1String = structure(c(1L, 1L, 2L, 2L, 1L, 1L, 5L, 4L, 
    1L, 1L, 2L, 5L, 1L, 5L, 1L, 1L, 1L, 5L, 1L, 3L), .Label = c("Strongly agree", 
    "Somewhat agree", "Neither agree nor disagree", "Somewhat disagree", 
    "Strongly disagree"), class = "factor")), row.names = c(NA, 
-20L), class = c("tbl_df", "tbl", "data.frame"))
Run Code Online (Sandbox Code Playgroud)

Rui*_*das 7

要将百分比放在条形中间,请使用position_fill(vjust = 0.5)并计算 中的比例geom_text。这些比例是占总价值的比例,而不是按条形划分的比例。

library(ggplot2)

colors <- c("#00405b", "#008dca", "#c0beb8", "#d70000", "#7d0000")
colors <- setNames(colors, levels(newDoto$Q29_1String))

ggplot(newDoto, aes(pid3lean, fill = Q29_1String)) +
  geom_bar(position = position_fill()) +
  geom_text(aes(label = paste0(..count../sum(..count..)*100, "%")),
            stat = "count",
            colour = "white",
            position = position_fill(vjust = 0.5)) +
  scale_fill_manual(values = colors) +
  coord_flip()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


scales具有自动格式化百分比的功能。

ggplot(newDoto, aes(pid3lean, fill = Q29_1String)) +
  geom_bar(position = position_fill()) +
  geom_text(aes(label = scales::percent(..count../sum(..count..))),
            stat = "count",
            colour = "white",
            position = position_fill(vjust = 0.5)) +
  scale_fill_manual(values = colors) +
  coord_flip()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


编辑

在要求按条形比例的评论之后,下面是首先仅使用基数 R 计算比例的解决方案。

tbl <- xtabs(~ pid3lean + Q29_1String, newDoto)
proptbl <- proportions(tbl, margin = "pid3lean")
proptbl <- as.data.frame(proptbl)
proptbl <- proptbl[proptbl$Freq != 0, ]

ggplot(proptbl, aes(pid3lean, Freq, fill = Q29_1String)) +
  geom_col(position = position_fill()) +
  geom_text(aes(label = scales::percent(Freq)),
            colour = "white",
            position = position_fill(vjust = 0.5)) +
  scale_fill_manual(values = colors) +
  coord_flip() +
  guides(fill = guide_legend(title = "29")) +
  theme_question_70539767()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


要添加到绘图中的主题

这是TarJae 的回答theme中定义的主题的副本,略有更改。

theme_question_70539767 <- function(){
  theme_bw() %+replace%
    theme(panel.grid.major = element_blank(),
          panel.grid.minor = element_blank(),
          panel.border = element_blank(),
          text = element_text(size = 19, family = "serif"),
          axis.ticks = element_blank(),
          axis.title.y = element_blank(),
          axis.title.x = element_blank(),
          axis.text.x = element_blank(),
          axis.text.y = element_text(color = "black"),
          legend.position = "top",
          legend.text = element_text(size = 10),
          legend.key.size = unit(1, "char")
    )
}
Run Code Online (Sandbox Code Playgroud)