我面临着ggplot2无法理解的,排序和堆积条形图的行为。
我已经读过一些关于它的问题(这里,这里等等),但是不幸的是我找不到适合我的解决方案。也许答案很简单,但我看不到。希望这不是一个骗子。
我的主要目标是基于ordering列(这里称为ordering)使每个堆栈独立地排序。
这里有一些数据:
library(dplyr)
library(ggplot2)
dats <- data.frame(id = c(1,1,1,2,2,3,3,3,3),
value = c(9,6,4,5,6,4,3,4,5),
ordering = c(1,2,3,2,3,1,3,2,4),
filling = c('a','b','c','b','a','a','c','d','b')) %>% arrange(id,ordering)
Run Code Online (Sandbox Code Playgroud)
因此,有一个ID,一个值,一个要用于排序的值和一个填充,数据就像在ordering列中一样应该在图中进行排序。
我试图绘制它:的想法是绘制一个x轴为的堆叠条形图id,值为value,由填充filling,但填充的值ordering按升序排列,即 ordering ,每个值的最大值在底部专栏。的顺序在filling某种程度上与数据集相同,即每一列都有独立的顺序。
您可以想象它们是假数据,因此id的数量可以变化。
id value ordering filling
1 1 9 1 a
2 1 6 2 b
3 1 4 3 c
4 2 5 2 b
5 2 6 3 a
6 3 4 1 a
7 3 4 2 d
8 3 3 3 c
9 3 5 4 b
Run Code Online (Sandbox Code Playgroud)
当我绘制它们时,有一些我不明白的地方:
library(dplyr)
dats$filling <- reorder(dats$filling, -dats$ordering)
ggplot(dats,aes(x = id,
y = value,
fill = filling)) +
geom_bar(stat = "identity",position = "stack") +
guides(fill=guide_legend("ordering"))
Run Code Online (Sandbox Code Playgroud)

第二个和第三个ID的顺序不正确,我应该具有原始数据集的顺序。
如果使用单独geom_bar的,则可以使订单不同。
dats %>%
ggplot(aes(x = id, y = value, fill = reorder(filling,-ordering))) +
geom_bar(stat = "identity", position = "stack", data = dats %>% filter(id == 1)) +
geom_bar(stat = "identity", position = "stack", data = dats %>% filter(id == 2)) +
geom_bar(stat = "identity", position = "stack", data = dats %>% filter(id == 3)) +
guides(fill=guide_legend("ordering"))
Run Code Online (Sandbox Code Playgroud)
更普遍:
bars <- map(unique(dats$id)
, ~geom_bar(stat = "identity", position = "stack"
, data = dats %>% filter(id == .x)))
dats %>%
ggplot(aes(x = id, y = value, fill = reorder(filling,-ordering))) +
bars +
guides(fill=guide_legend("ordering"))
Run Code Online (Sandbox Code Playgroud)
问题是,在您的情况下,不同的条应filling以不同的顺序使用相同的值(级别)。这与ggplot工作方式相冲突:采用因子水平(已经具有一定顺序),并对每个柱以相同的方式应用它们。
那么一种解决方法是...创建许多因子水平。
ggplot(dats, aes(x = id, y = value, fill = interaction(-ordering, id))) +
geom_bar(stat = "identity", position = "stack")
Run Code Online (Sandbox Code Playgroud)
现在,由于过于详细,因此过于“慷慨”。但是,我们现在可以做的是处理图例和不同的颜色:
dats <- arrange(dats, id, -ordering)
aux <- with(dats, match(sort(unique(filling)), filling))
ggplot(dats, aes(x = id, y = value, fill = interaction(-ordering, id))) +
geom_bar(stat = "identity", position = "stack") +
scale_fill_manual("Ordering", values = scales::hue_pal()(4)[dats$filling],
labels = with(dats, filling[aux]),
breaks = with(dats, interaction(-ordering, id)[aux]))
Run Code Online (Sandbox Code Playgroud)
在这里,我首先重新排列datsas 的行,以免以后再做。然后aux是辅助向量
aux
# [1] 3 2 1 8
Run Code Online (Sandbox Code Playgroud)
给予其中水平的任意位置(每个)a,b,c,和d(以该顺序)出现在dats,这再次是有用的后面。然后,我只需设置相应的比例值,标签和折线...最后,我使用它scales::hue_pal来恢复原始调色板。