【问题标题】:How to order bars in a stacked barplot along with putting % labels如何在堆叠的条形图中排序条形以及放置 % 标签
【发布时间】:2018-12-22 17:15:08
【问题描述】:

我的数据的最小子集是

mydata <- read.table(header = TRUE, text= "
                     Product    Characteristic  Product_category
AA  Functional  A
                     AB Functional  A
                     AB Portable    A
                     BA Portable    B
                     BA Quality B
                     BB Quality B
                     BA Bright  B
                     BB Sound   B
                     BB Sound   B
                     BC Sound   B
                     BC Sound   B
                     BC Work    B
                     CA Functional  C
                     CA Functional  C
                     CA Functional  C
                     CA Functional  C
                     CB Functional  C
                     CC Functional  C
                     CC Functional  C
                     CC Functional  C
                     CC Functional  C
                     CC Portable    C
                     CC Design  C
                     CD Quality C
                     CD Quality C
                     CD Output  C
                     CD Noise   C
                     CD Noise   C
                     CD Component   C
                     CD Component   C

                     ")

我想制作 3 个条形图,对应于 3 个产品类别中的每一个,其中 x=Characteristic 和 y 轴具有每个特征的计数。此外,我想将条与 Product 堆叠在一起。因此,假设 Product_category A 的条形图代码是 -

mydata %>% filter(Product_category == "A") %>% 
  ggplot(aes(x=Characteristic, fill = Product)) + geom_bar(width = 0.2) + coord_flip()

这部分很简单。我在两件事上苦苦挣扎-我想按每个特征的计数降序排列堆叠的条形图。该数据集是我的数据集的最小子集,因此默认情况下,条形图可能显示为有序,但在我的实际数据集中它们不是。我想做的第二件事是用百分比标记每个条形图,以便百分比在每个产品类别内 - 公式 = count(Characteristic)/sum(count(Characteristic))。所以我希望我的最终图表如下所示 -

mydata %>% filter(Product_category == "A") %>% 
  group_by(Characteristic) %>%
  summarize(counts = n()) %>% arrange(counts) %>%
  mutate(Characteristic = factor(Characteristic, Characteristic), perc = counts/sum(counts)) %>%
  ggplot(aes(x=Characteristic, y = counts)) + 
  geom_bar(stat = "identity", width = 0.4) + 
  theme(axis.text.x=element_blank()) + 
  geom_text(aes(label = paste(round(perc*100, digits = 1),"%",sep = "")), hjust = -0.2, size = 2.8, position = position_dodge(width = 0.7), inherit.aes = TRUE) + 
  coord_flip()

唯一的区别是我希望每个条都按产品堆叠,这样我就可以直观地看到每个产品在每个特性中的份额。我尝试了很多东西,但每一个都很冗长,仍然没有得到想要的结果。这样做最整洁的方法是什么?

【问题讨论】:

  • 我想补充一点,这里还有其他关于添加标签的帖子 - stackoverflow.com/questions/30656846/… 但我的问题是实现条形图和百分比标签的排序,并同时将条形图与 Product 堆叠在一起时间。

标签: r sorting ggplot2 labels stacked


【解决方案1】:

您应该可以使用一点dplyr 和使用forcats 的排序因子来做到这一点。因为,正如您所指出的,在您过滤的类别中没有很多观察结果,所以我取出过滤只是为了用更多数据来说明,并为了简化而跳过了情节中的一些细节例子。这样做的关键是将CharacteristicProduct 设置为因子,然后使用Product 设置填充,这样您就可以在每个特性中为每个产品堆叠区域。

您还可以简化其他一些事情:geom_col 等同于 geom_bar(stat = "identity"),而scales::percent 将执行您拥有的百分比格式。为了在每个条形块中包含文本,请使用 position_stackvjust = 0.5 使标签居中。

library(tidyverse)

mydata %>%
  # filter(Product_category == "A") %>%
  group_by(Characteristic, Product) %>%
  summarise(counts = n()) %>%
  mutate(perc = round(counts / sum(counts), digits = 3)) %>%
  ungroup() %>%
  mutate(Characteristic = as.factor(Characteristic) %>% fct_reorder(counts, .fun = sum)) %>%
  arrange(Characteristic, perc) %>%
  mutate(Product = as.factor(Product) %>% fct_reorder(perc, .desc = F)) %>%
  ggplot(aes(x = Characteristic, y = counts, fill = Product)) +
    geom_col(position = "stack") +
    geom_text(aes(label = scales::percent(perc)), 
              position = position_stack(vjust = 0.5), size = 3) +
    coord_flip()

reprex package (v0.2.0) 于 2018 年 7 月 14 日创建。

【讨论】:

  • 谢谢卡米尔。我不希望百分比在每个特性内,而是在每个产品类别内。所以 ggplot 之前的 group_by 应该只有内部的特性而不是产品。我还希望在每个条的末尾只显示整个条的百分比,而不是针对每个产品对应的条的所有子部分,因此很容易看到条的总数。但如果我这样做,然后在 ggplot 中使用 fill=Product,我会收到错误 - 'FUN 中的错误(X[[i]],...):找不到对象'Product''
  • 所以%的公式应该符合如下代码:mydata %&gt;% group_by(Characteristic) %&gt;% summarize(counts = n()) %&gt;% arrange(counts) %&gt;% ungroup() %&gt;% mutate(Characteristic = factor(Characteristic, Characteristic), perc = counts/sum(counts)) %&gt;% ggplot(aes(x=Characteristic, y = counts, fill=Product)) + geom_col(position = "stack") + theme(axis.text.x=element_blank()) + geom_text(aes(label = scales::percent(perc)), hjust = -0.2, size = 2.8, position = position_dodge(width = 0.7), inherit.aes = TRUE) + coord_flip()感谢简化代码!
  • 麻烦的是,为了将分类变量的计数标签放在条形图上,您需要在编写ggplot之前对其进行group_by和summarize(count = n())。但是在 ggplot 中,如果您尝试使用未包含在 group_by 中的第二个分类变量堆叠条形图或刻面图,则会引发错误。如何克服这个问题?
  • 我现在不清楚您希望如何按产品堆叠条形图。我想你可以在你的aes 中使用group = Product 但不能填充......?通过summarize 在您的评论中运行该代码,您会看到,如果您使用summarize,仅对Characteristic 进行分组就会失去Product。也许你想mutate 而不是得到一个真实的总结?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-21
  • 1970-01-01
  • 2022-01-18
  • 2012-01-04
  • 2023-01-21
相关资源
最近更新 更多