如何在ggplot中绘制堆叠且分组的条形图?

11

我有一个如下的数据框:

id    month     type    count
___  _______   ______   ______
1      1          1       10
1      1          2       09
1      1          3       26
1      2          1       60
1      2          2       90
2      2          3       80
2      1          1       10
2      1          2       09
2      1          3       26
2      2          1       60
2      2          2       90
2      2          3       80
3      1          1       10
3      1          2       09
3      1          3       26
3      2          1       60
3      2          2       90
3      2          3       80

我认为最好的可视化方式是类似下面这样的堆叠组合条形图:

Stacked and Grouped Bar Chart

因此,我尝试使用

ggplot(df,aes(x=id,y=count,fill=month))+geom_bar(stat="identity",position=position_dodge())+geom_text(aes(label=count),size=3)

这提供了一个情节,与我的预期有些不同。任何帮助都将不胜感激。

2个回答

17

使用tidyverse套件和 facet_grid 可以更加清晰地解决这个问题:

library(tidyverse)
read_tsv("tmp.tsv", col_types = "ccci") %>%  
ggplot(aes(x=month, y=count, fill=type)) + geom_col() + facet_grid(.~id)

堆积条形图并排显示

请注意在col_types参数中,您必须将前三列指定为“字符串”,否则它看起来不太好。最好用有意义的内容替换数字代码(例如,将月份变成有序因子:“一月”,“二月”而不是1、2;类型和ID也可以采用类似方式)。


15

假设你想将id绘制在x轴上,按月份并将不同类型叠加显示,可以通过月份拆分数据框,并为每个月添加一个条形图层,在第二个月的条形图上将x平移一定量以使它们能够分开:

barwidth = 0.35

month_one <- filter(df, month == 1) %>% 
    group_by(id) %>% arrange(-type) %>% 
    mutate(pos = cumsum(count) - count / 2)   # calculate the position of the label

month_two <- filter(df, month == 2) %>% 
    group_by(id) %>% arrange(-type) %>% 
    mutate(pos = cumsum(count) - count / 2)

ggplot() + 
    geom_bar(data = month_one, 
             mapping = aes(x = id, y = count, fill = as.factor(type)), 
             stat="identity", 
             position='stack', 
             width = barwidth) + 
    geom_text(data = month_one, 
              aes(x = id, y = pos, label = count )) + 
    geom_bar(data = filter(df, month==2), 
             mapping = aes(x = id + barwidth + 0.01, y = count, fill = as.factor(type)), 
             stat="identity", 
             position='stack' , 
             width = barwidth) + 
    geom_text(data = month_two, 
              aes(x = id + barwidth + 0.01, y = pos, label = count )) + 
    labs(fill  = "type")
给出:

在此输入图片描述


dput(df)
structure(list(id = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L), month = c(1L, 1L, 1L, 2L, 2L, 
2L, 1L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 2L, 2L, 2L), type = c(1L, 
2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 
3L), count = c(10L, 9L, 26L, 60L, 90L, 80L, 10L, 9L, 26L, 60L, 
90L, 80L, 10L, 9L, 26L, 60L, 90L, 80L)), .Names = c("id", "month", 
"type", "count"), class = "data.frame", row.names = c(NA, -18L
))

非常感谢。所以我们需要分离月份,然后将图形连接起来。是这样工作的吗? - Ricky
你同时使用了stackdodge条形图。对我来说,目前还不清楚是否有自动绘制这种图形的方法。 - Psidom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接