ggplot2:创建有序组条形图 - (使用重新排序)
ggplot2: create ordered group bar plot - (use reorder)
我想在保持秩序的同时创建分组条形图。如果它是单列而不是分组条形图,则使用重新排序功能是显而易见的。但不确定如何在融化的 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()
以上情节没有订单,如果我想通过 win 订购情节,我可以执行以下操作:
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()
上面的 ggplot 是无序的。
但是我是怎么做有序组条形图的(升序方式)
您的问题提出的挑战是如何根据熔化列中的子集值对因子 Team1
重新排序。
@alistaire 和@joran 对你的问题的评论 link 给出了很好的答案。
tl;dr 答案是使用 levels()
.
将原始未熔化 data.frame 的顺序应用到新顺序
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()
这不是问题。
最简单的方法是不要在熔化中丢弃你订购的团队:
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")
)
至于最简单的方法,我建议在熔化时只保留 orderedTeam
变量。您的代码似乎很难将其排除在外,而将其保留在其中却很容易。
我想在保持秩序的同时创建分组条形图。如果它是单列而不是分组条形图,则使用重新排序功能是显而易见的。但不确定如何在融化的 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()
以上情节没有订单,如果我想通过 win 订购情节,我可以执行以下操作:
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()
上面的 ggplot 是无序的。
但是我是怎么做有序组条形图的(升序方式)
您的问题提出的挑战是如何根据熔化列中的子集值对因子 Team1
重新排序。
@alistaire 和@joran 对你的问题的评论 link 给出了很好的答案。
tl;dr 答案是使用 levels()
.
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()
这不是问题。
最简单的方法是不要在熔化中丢弃你订购的团队:
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")
)
至于最简单的方法,我建议在熔化时只保留 orderedTeam
变量。您的代码似乎很难将其排除在外,而将其保留在其中却很容易。