如何在ggplot中按大小对堆积条形图类别进行排序?

4

我正在尝试通过变量的大小重新排序ggplot条形图中的类别,首先是最大的类别,其次是越来越小的类别。我已经尝试过以几种方式更改顺序,但似乎只能手动设置顺序,这对于大数据集并不是很有帮助。

例如: 假设我有以下数据:

mydata <- read.table(header=TRUE, text="
shop    fruit   varieties   km_away
shop1   apple   0   12
                     shop1  banana  0   12
                     shop1  pear    2   12
                     shop1  melon   1   12
                     shop1  orange  1   12
                     shop1  peach   3   12
                     shop1  apricot 6   12
                     shop1  lime    1   12
                     shop2  apple   1   1
                     shop2  banana  0   1
                     shop2  pear    2   1
                     shop2  melon   2   1
                     shop2  orange  5   1
                     shop2  peach   4   1
                     shop2  apricot 11  1
                     shop2  lime    0   1
                     shop3  apple   0   2
                     shop3  banana  1   2
                     shop3  pear    2   2
                     shop3  melon   1   2
                     shop3  orange  4   2
                     shop3  peach   1   2
                     shop3  apricot 11  2
                     shop3  lime    1   2
                     shop4  apple   0   5
                     shop4  banana  0   5
                     shop4  pear    3   5
                     shop4  melon   2   5
                     shop4  orange  6   5
                     shop4  peach   1   5
                     shop4  apricot 9   5
                     shop4  lime    0   5
                     ")

我可以用如下方式有益地进行想象:
library(ggplot2)
library(RColorBrewer)
p <- ggplot(data = mydata, aes(x=reorder(shop, km_away), y=varieties, fill=fruit))+
  geom_bar(stat="identity") + coord_flip()+scale_fill_brewer(palette="Accent")
p

但是我该如何告诉ggplot先绘制杏子,然后是橙子等等?这将使得在不同商店之间进行视觉比较各个类别变得更加容易。

1个回答

3
您可以先获取一个按您感兴趣的数量排序的类别向量:
fruit_levels <- names(sort(tapply(mydata$varieties, mydata$fruit, sum)))

然后,在调用ggplot时,将fill映射到具有相应级别的因子变量:

p <- ggplot(data = mydata, 
    aes(x=reorder(shop, km_away), y=varieties, 
        fill=factor(fruit, levels = fruit_levels)))+
  geom_bar(stat="identity") + coord_flip()+
  scale_fill_brewer(name = "fruit", palette="Accent") 
p

输出:

输入图像描述


更新. 更直接的方法是重新排列原始数据框中的因子水平,并像您原来的代码一样调用ggplot

mydata$fruit <- reorder(mydata$fruit, mydata$varieties, sum)
p <- ggplot(data = mydata, aes(x=reorder(shop, km_away), y=varieties, fill=fruit))+
  geom_bar(stat="identity") + coord_flip()+scale_fill_brewer(palette="Accent")
p

更新2。 在旧版本的 ggplot2 (2.0 之前的版本),尝试指定 order 美学属性:

p <- ggplot(data = mydata, aes(x=reorder(shop, km_away), 
                               y=varieties, 
                               fill=fruit, order=fruit)) +
  geom_bar(stat="identity") + coord_flip()+scale_fill_brewer(palette="Accent")
p

如果您想要逆序排序,请在排序变量前面添加负号:

reorder(mydata$fruit, -mydata$varieties, sum)

当我输入您的代码时,水果仍然按字母顺序排序,而不是按值排序。我错过了什么吗? - setbackademic
如果你运行 reorder(mydata$fruit, mydata$varieties, sum) ,输出会报告“Levels(水平)”的正确顺序吗? 它应该读取Levels: apple banana lime melon peach pear orange apricot - Weihuang Wong
reorder(mydata$fruit, mydata$varieties, sum) [1] 苹果 香蕉 梨 瓜 橙子 桃子 杏子 青柠檬 苹果 香蕉 梨 瓜 橙子 桃子 杏子 青柠檬 苹果
[18] 香蕉 梨 瓜 橙子 桃子 杏子 青柠檬 苹果 香蕉 梨 瓜 橙子 桃子 杏子 青柠檬
attr(,"scores") 苹果 香蕉 青柠檬 瓜 桃子 梨 橙子 杏子 1 1 2 6 9 9 16 37 Levels: 苹果 香蕉 青柠檬 瓜 桃子 梨 橙子 杏子
- setbackademic
然后当你调用 ggplot 时,它应该按照这个顺序进行填充。也许重新启动 R 并尝试再次运行代码? - Weihuang Wong
我已在两台不同的机器上运行了此代码,但无法重现您的图形。在尝试重新排序之前,您的两个代码部分都生成与以前相同的图形。 - setbackademic
显示剩余3条评论

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