在 R 中汇总并创建堆积条形图

Summarise and create a stacked bar chart in R

对于一群人,我有一个关于他们属于哪个类别的固定时间序列。我想按类别总结这个人口随时间的构成,作为 R 中的堆积条形图。例如:

set.seed(1)
id <- seq(1:25)
t1 <- sample(LETTERS[1:5], 25, replace=TRUE)
t2 <- sample(LETTERS[1:5], 25, replace=TRUE, prob=c(0.1,0.1,0.1,0.1,0.6))
t3 <- sample(LETTERS[1:5], 25, replace=TRUE, prob=c(0.2,0.1,0.2,0.1,0.4))

df <- data.frame(cbind(id, t1, t2, t3))

频率:

> table(df$t1)

A B C D E 
7 6 3 2 7 
> table(df$t2)

 B  C  D  E 
 3  4  5 13 
> table(df$t3)

 A  B  C  D  E 
 4  2  5  4 10 

所以,在时间段 1,25 个中有 7 个属于 A 类,6 个属于 B 类,而在时间段 2,none 属于 A 类,3 个属于 B 类,等等。图表看起来像这个(来自EXCEL):


这可以用 ggplot 制作吗?谢谢

这可以通过首先使用 pivot_longer 重塑为 'long' 格式来完成,然后获取频率 count 并将汇总的 'n' 用作 'y'在 ggplot aes 中,同时将 'x' 指定为 'name' 并将 fill 指定为 'value' 从 pivot_longer[=18= 创建的列]

library(dplyr)
library(tidyr)
library(ggplot2)
df %>%
    pivot_longer(cols = everything()) %>% 
    count(name, value) %>% 
    ggplot(aes(x = name, y = n, fill = value)) +
        geom_col()

如果我们需要比例而不是计数,

df %>%
      pivot_longer(cols = everything()) %>% 
      count(name, value) %>%
      group_by(name) %>%
      mutate(prop =  n/sum(n)) %>% 
      ggplot(aes(x = name, y = prop, fill = value)) + 
         geom_col() +
         scale_y_continuous(labels= scales::percent)

这里有一个选项data.table

library(dplyr)
library(data.table)
library(ggplot2)

melt(setDT(df), id.var = "id")[, .N, .(variable, value)][, perc := N / sum(N), variable] %>%
  ggplot(aes(x = variable, y = perc, fill = value)) +
  geom_bar(stat = "identity") +
  scale_y_continuous(labels = scales::percent)