ggplot2:创建有序组条形图 - (使用重新排序)

时间:2016-05-02 16:00:46

标签: r ggplot2 geom-bar

我想在保持秩序的同时创建分组条形图。如果是单列而不是分组条形图,则使用重新排序功能是显而易见的。但不确定如何在融化的data.frame上使用它。

以下是代码示例的详细说明:

让我们说我们有以下data.frame:

d.nfl <- data.frame(Team1=c("Vikings", "Chicago", "GreenBay", "Detroit"), Win=c(20, 13, 9, 12))

在翻转时绘制简单的条形图。

ggplot(d.nfl, aes(x = Team1, y=Win)) + geom_bar(aes(fill=Team1), stat="identity") + coord_flip()

上面的情节将没有订单,如果我想通过赢取订单,我可以做以下:

d.nfl$orderedTeam <- reorder(d.nfl$Team1, d.nfl$Win)
ggplot(d.nfl, aes(x = orderedTeam, y=Win)) + geom_bar(aes(fill=orderedTeam), stat="identity") + coord_flip()

现在假设我们添加另一列(到原始数据框)

d.nfl$points <- c(12, 3, 45, 5)

     Team1 Win points
1  Vikings  20     12
2  Chicago  13      3
3 GreenBay   9     45
4  Detroit  12      5

要生成分组条形图,首先我们需要将其融合:

library(reshape2)
> d.nfl.melt <- melt(d.nfl[,c('Team1','Win','points')],id.vars = 1)
> ggplot(d.nfl.melt,aes(x = Team1,y = value)) + geom_bar(aes(fill = variable),position = "dodge", stat="identity") + coord_flip()

enter image description here

以上ggplot是无序的。

但我如何订购组合条形图(以升序方式)

2 个答案:

答案 0 :(得分:3)

这不是问题。

最简单的方法是不要在融化中丢弃您订购的团队:

d.nfl.melt <- melt(d.nfl,id.vars = c("Team1", "orderedTeam"))

或者,我们可以在融化后使用reorder,只使用Win元素计算排序:

d.nfl.melt$ordered_after_melting = reorder(
    d.nfl.melt$Team1,
    X = d.nfl.melt$value * (d.nfl.melt$variable == "Win")
)

另一个想法是从原始有序列中取出levels并将它们应用于融化因子:

d.nfl.melt$copied_levels = factor(
    d.nfl.melt$Team1,
    levels = levels(d.nfl$orderedTeam)
)

所有三种方法都给出了相同的结果。 (我省略了coord_flips,因为它们没有在问题中添加任何内容,但您当然可以将它们添加回来。)

gridExtra::grid.arrange(
    ggplot(d.nfl.melt,aes(x = orderedTeam, y = value)) + 
        geom_bar(aes(fill = variable),position = "dodge", stat="identity"),
    ggplot(d.nfl.melt,aes(x = ordered_after_melting, y = value)) + 
        geom_bar(aes(fill = variable),position = "dodge", stat="identity"),
    ggplot(d.nfl.melt,aes(x = copied_levels, y = value)) + 
        geom_bar(aes(fill = variable),position = "dodge", stat="identity")
)

enter image description here

至于最简单的,我建议只在融化时保持orderedTeam变量。你的代码似乎很难将它遗漏掉,很容易将其保留下来。

答案 1 :(得分:2)

您的问题提出的挑战是如何根据融化列中的子集值对因子Team1重新排序。

来自@alistaire和@joran的问题评论链接到了很棒的答案。 tl; dr答案是使用levels()将原始未融合数据框架的排序应用于新的。{/ p>

library(reshape2)
#Picking up from your example code:
d.nfl.melt <- melt(d.nfl[,c('Team1','Win','points')],id.vars = 1)
levels(d.nfl.melt$Team1)
#Current order is alphabetical
#[1] "Chicago"  "Detroit"  "GreenBay" "Vikings" 

#Reorder based on Wins (using the same order from your earlier, unmelted data.frame)
d.nfl.melt$Team1 <- factor(d.nfl.melt$Team1, levels = levels(d.nfl$orderedTeam)) #SOLUTION
levels(d.nfl.melt$Team1)
#New order is ascending by wins
#[1] "GreenBay" "Detroit"  "Chicago"  "Vikings" 

ggplot(d.nfl.melt,aes(x = Team1,y = value)) + 
  geom_bar(aes(fill = variable),position = "dodge", stat="identity") + coord_flip()

enter image description here