如何在堆积条形图中使用百分比作为标签?

fak*_*hek 5 r ggplot2

我正在尝试将百分比数字显示为 ggplot2 中堆叠条形图的条形内的标签。我发现了 3 年前的一些其他帖子,但我无法重现它:How to draw stacked bar in ggplot2 that show Percentages based on group?

那篇文章的答案几乎正是我想要做的。

这是我的数据的一个简单示例:

df = data.frame('sample' = c('cond1','cond1','cond1','cond2','cond2','cond2','cond3','cond3','cond3','cond4','cond4','cond4'),
                'class' = c('class1','class2','class3','class1','class2','class3','class1','class2','class3','class1','class2','class3'))
ggplot(data=df, aes(x=sample, fill=class)) + 
    coord_flip() +
    geom_bar(position=position_fill(reverse=TRUE), width=0.7)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我希望每个条形都显示百分比/分数,因此在本例中它们都是 33%。实际上,如果能够即时计算这些值就好了,但如果有必要,我也可以手动传递百分比。有人可以帮忙吗?

附带问题:如何减少栏之间的空间?我也找到了很多答案,但他们建议使用widthin 参数position_fill(),该参数似乎不再存在。

非常感谢!

编辑:

到目前为止,有两个例子准确地展示了我所要求的内容(非常感谢您如此迅速地回复),但是当将其应用于我的真实数据时它们失败了。以下是示例数据,仅添加了另一个元素以显示发生的情况:

df = data.frame('sample' = c('cond1','cond1','cond1','cond2','cond2','cond2','cond3','cond3','cond3','cond4','cond4','cond4','cond1'),
                'class' = c('class1','class2','class3','class1','class2','class3','class1','class2','class3','class1','class2','class3','class2'))
Run Code Online (Sandbox Code Playgroud)

本质上,我希望每个类别/条件组合只有一个标签。

Mik*_* H. 5

我认为OP想要的是在酒吧的实际部分上贴上标签。我们可以使用以下方法data.table来获取计数百分比和格式化百分比,然后使用以下方法进行绘图ggplot

library(data.table)
library(scales)
dt <- setDT(df)[,list(count = .N), by = .(sample,class)][,list(class = class, count = count,
                percent_fmt = paste0(formatC(count*100/sum(count), digits = 2), "%"),
                percent_num = count/sum(count)
                ), by = sample]

ggplot(data=dt, aes(x=sample, y= percent_num, fill=class)) +   
  geom_bar(position=position_fill(reverse=TRUE), stat = "identity", width=0.7) +
  geom_text(aes(label = percent_fmt),position = position_stack(vjust = 0.5)) + coord_flip()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

编辑:另一种解决方案,您可以在聚合中计算标签的 y 值。这样我们就不必依赖position_stack(vjust = 0.5)

dt <- setDT(df)[,list(count = .N), by = .(sample,class)][,list(class = class, count = count,
               percent_fmt = paste0(formatC(count*100/sum(count), digits = 2), "%"),
               percent_num = count/sum(count),
               cum_pct = cumsum(count/sum(count)),
               label_y = (cumsum(count/sum(count)) + cumsum(ifelse(is.na(shift(count/sum(count))),0,shift(count/sum(count))))) / 2
), by = sample]

ggplot(data=dt, aes(x=sample, y= percent_num, fill=class)) +   
  geom_bar(position=position_fill(reverse=TRUE), stat = "identity", width=0.7) +
  geom_text(aes(label = percent_fmt, y = label_y)) + coord_flip()
Run Code Online (Sandbox Code Playgroud)