【问题标题】:Stacked bar chart with percentage labels带有百分比标签的堆积条形图
【发布时间】:2019-03-17 15:36:22
【问题描述】:

我创建了一个堆积条形图,其中条形代表人口的百分比。我想将标签添加到 65+ 类别(或所有 3 个类别,如果不可能仅针对 1 个类别)显示每年的 % 值。如果我添加geom_text(label = datm$value),条形将变得非常小,因为标签代表绝对值而不是百分比。这是我的代码:

dat <- read.table(text = "2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018
0-20 24.0 23.9 23.7 23.5 23.3 23.1 22.9 22.7 22.5 22.3 22.2
20-65 61.3 61.2 61.0 60.9 60.5 60.1 59.8 59.6 59.3 59.1 59.0
65+ 14.8 15.0 15.3 15.6 16.2 16.8 17.4 17.7 18.2 18.5 18.8", sep = " ", header = TRUE)

library(reshape)
datm <- melt(cbind(dat, ind = rownames(dat)), id.vars = c('ind'))

library(scales)
library(ggplot2)
ggplot(datm,aes(x = variable, y = value, fill = ind)) + 
  geom_bar(position = "fill",stat = "identity") + 
  scale_x_discrete(labels = c('2008', '2009', '2010', '2011', '2012', '2013', 
                              '2014', '2015', '2016', '2017', '2018')) + 
  scale_y_continuous(labels = percent_format()) + 
  xlab('Year') + 
  ylab('% of population') + 
  ggtitle('Demographic trend in the Netherlands') + 
  scale_fill_manual(values = c("green", "blue", "darkgray"))

【问题讨论】:

    标签: r ggplot2


    【解决方案1】:

    你可以试试这个。下面在cmets中的解释:

    library(dplyr)
    
    # calculate percentage within each year
    datm2 <- datm %>%
      group_by(variable) %>%
      mutate(p = value / sum(value)) %>%
      ungroup()
    
    > head(datm2)
    # A tibble: 6 x 4
      ind   variable value     p
      <fct> <fct>    <dbl> <dbl>
    1 0-20  X2008     24   0.240
    2 20-65 X2008     61.3 0.612
    3 65+   X2008     14.8 0.148
    4 0-20  X2009     23.9 0.239
    5 20-65 X2009     61.2 0.611
    6 65+   X2009     15   0.150
    
    ggplot(datm2, aes(x = variable, y = value, fill = ind)) + 
      geom_col(position = "fill") + # geom_col is equivalent to geom_bar(stat = "identity")
      geom_text(aes(label = scales::percent(p),          # add layer for percentage values
                    alpha = ifelse(ind == "65+", 1, 0)), # only visible for 65+ category
                position = position_fill(vjust = 0.5)) + # follow barplot's position
      scale_x_discrete(labels = c('2008', '2009', '2010', '2011', '2012', '2013', 
                                  '2014', '2015', '2016', '2017', '2018')) + 
      scale_y_continuous(labels = percent_format()) + 
      scale_alpha_identity() +
      xlab('Year') + 
      ylab('% of population') + 
      ggtitle('Demographic trend in the Netherlands') + 
      scale_fill_manual(values = c("green", "blue", "darkgray"))
    

    【讨论】: