按 R 中的累积值对堆积条形图进行排序

Sort stacked bar plot by cumulative value in R

我是 R 的新手,我正在尝试获取堆积条形图。我的数据如下所示:

    name    value1  value2
1   A       1118    239
2   B       647     31
3   C       316     1275
4   D       2064    230
5   E       231     85

我需要一个带有堆叠值的水平条形图,这是我有限的 R 技能所能获得的(其中大部分也是复制粘贴的):

melted <- melt(data, id.vars=c("name"))

melted$name <- factor(
  melted$name, 
  levels=rev(sort(unique(melted$name))), 
  ordered=TRUE
)

melted2 <- melted[order(melted$value),]

ggplot(melted2, aes(x= name, y = value, fill = variable)) + 
  geom_bar(stat = "identity") +
  coord_flip()

我什至花了几个小时才达到这一点, 就外观而言,我很满意,这是生成的输出

我现在要做的是按总值对条形图进行排序(首先是 D,然后是 C、A、B、E)。我用谷歌搜索并尝试了一些 reorderorder 东西,但我就是无法让它按照我想要的方式运行。我确定解决方案必须非常简单,所以我希望你们能帮助我。

提前致谢!

好吧,我并没有因为 ggplot 的所有最新变化而沮丧或跟不上,但这是您可以补救的一种方法

我用你的想法设置了 name 的因子水平,但基于分组总和。您可能还会发现 order = variable 在某些时候很有用,它会根据变量对条形颜色进行排序,但此处不需要

data <- read.table(header = TRUE, text = "name    value1  value2
1   A       1118    239
2   B       647     31
3   C       316     1275
4   D       2064    230
5   E       231     85")

library('reshape2')
library('ggplot2')

melted <- melt(data, id.vars=c("name"))

melted <- within(melted, {
  name <- factor(name, levels = names(sort(tapply(value, name, sum))))
})

levels(melted$name)
# [1] "E" "B" "A" "C" "D"

ggplot(melted, aes(x= name, y = value, fill = variable, order = variable)) + 
  geom_bar(stat = "identity") +
  coord_flip()

另一种选择是使用 dplyr 包在数据框中设置总计列并使用它进行排序。 该方法看起来像这样。

m <- melted %>% group_by(name) %>% 
     mutate(total = sum(value) ) %>% 
     ungroup() %>%
     arrange(total) %>%
     mutate(name = factor(name, levels = unique(as.character(name))) )

ggplot(m, aes(x = name, y = value, fill = variable)) + geom_bar(stat = 'identity') + coord_flip()

注意尝试下面的代码。

  • 使用 tidyr 包代替 reshape2

    library(ggplot2)
    library(dplyr)
    library(tidyr)
    
    data <- read.table(text = "
                       class value1 value2
                       A     1118   239
                       B     647    31
                       C     316    1275
                       D     2064   230
                       E     231    85", header = TRUE)
    
        pd <- gather(data, key, value, -class) %>% 
          mutate(class = factor(class, levels = tapply(value, class, sum) %>% sort %>% names))
    
        pd %>% ggplot(aes(x = class, y = value, fill = key, order = class)) + 
          geom_bar(stat = "identity") +
      coord_flip()