如何按数字向量的降序显示ggplot2中的条形?

Posted

技术标签:

【中文标题】如何按数字向量的降序显示ggplot2中的条形?【英文标题】:How to show bars in ggplot2 in descending order of a numeric vector? 【发布时间】:2013-09-19 21:28:50 【问题描述】:
df <- data.frame (Categories=c("Alpha Category", "Alpha Category", 
                               "Alpha Category", "Bravo Category", 
                               "Bravo Category", "Bravo Category", 
                               "Charlie Category", "Charlie Category", 
                               "Charlie Category"),  
                  choices=c("alpha1", "alpha2", "alpha3", "bravo1", 
                            "bravo2", "bravo3", "charlie1", "charlie2",
                            "charlie3")  , 
                  ratings=c(20,60,40, 55,75,25,65,35,45))    
df.plot <- ggplot(df, aes(Categories, ratings, fill = choices))
           + geom_bar(position="dodge", stat="identity") 
           + coord_flip()    
df.plot <- df.plot 
           + theme_classic(base_size = 16, base_family = "")  
           + scale_fill_brewer(palette="Paired")    
df.plot <- df.plot 
           + scale_y_continuous(breaks=seq(0,100,by=10),limits=c(0,80) )  
           + ylab("Ratings")  
           + theme(axis.text.y = element_text(size=16)) #change font size of y axis label   
df.plot

最重要的是,我想按其“评分”的降序显示每个“类别”中的“选择”,例如这里的“查理类别”将显示 charlie1,然后是 charlie3,然后是 charlie2。

老实说,我在网上找了大约一周的解决方案,但找不到。我目前的想法是我应该将选择转换为因素,但我还没有弄清楚如何正确地做到这一点。

其次重要的是,如果可以从上到下列出“类别”,“Alpha 类别”、“Bravo 类别”、“Charlie 类别”,而不是按照似乎发生在坐标翻转

【问题讨论】:

【参考方案1】:
library(ggplot2)
df.plot <- ggplot(df, aes(x=Categories,y=reorder(choices,ratings), fill = choices)) +
  geom_bar(position = "dodge", stat = "identity") + coord_flip() +
  scale_x_discrete(limits = rev(levels(df$Categories)))

【讨论】:

你能告诉我如何使用reorder,在这种情况下我应该如何编写代码? +1 可以在ggplot 中做任何事情!看看是否有可能摆脱我的旧习惯,在 ggplot 调用之前准备所有数据...... 这几乎就在那里,但现在我的缩放不起作用。 “说错误:提供给连续比例的离散值。我们能找到一种方法来解决这个问题吗?df.plot 我遇到了同样的错误。可能你需要在那里做一些调整。【参考方案2】:

这个答案没有利用ggplot 中的可能性来转换变量和比例(参见@Metric 的干净答案),而是预先转换了变量。

在每个类别中,根据评分重新排序选择。检查“选择”是否为 character。如果它是factor,您应该使用as.character 转换为字符,因为使用因子作为输入重新排序并不能得到我们想要的(见下文)。

str(df$choices)
# chr [1:9] "alpha1" "alpha2" "alpha3" ...

library(plyr)
df <- ddply(.data = df, .variables = .(Categories), mutate,
            choices = reorder(choices, ratings))

“类别”的反向级别

df$Categories <- as.factor(df$Categories)
levels(df$Categories) <- rev(levels(df$Categories))

情节

df.plot <- ggplot(df, aes(x = Categories, y = ratings, fill = choices)) +
  geom_bar(position = "dodge", stat = "identity") +
  coord_flip() +
  theme_classic(base_size = 16, base_family = "") +
  scale_fill_brewer(palette = "Paired") +
  scale_y_continuous(breaks = seq(0, 100, by = 10), limits = c(0, 80)) +
  ylab("Ratings")  +
  theme(axis.text.y = element_text(size = 16))   

df.plot

根据@Michael Bellhouse 的评论进行编辑 - “似乎 alpha 类别已排名但不是 bravo 或 charlie”

当“choices”是一个字符时,在ddply 中生成和重新排序的因子级别基于“choices”的每个子集。哪个工作正常。另一方面,当“选择”是原始数据中的一个因素时,其级别基于数据中存在的所有级别。在ddply 中,“选择”级别的子集随后被重新排序,但重新排序发生在整个级别集内。这会导致三组相互冲突的级别,并且只使用第一组。

# reorder character version
ll <- dlply(.data = df, .variables = .(Categories), mutate,
            choices.ro = reorder(choices, ratings))

# check levels
lapply(ll, function(x) levels(x$choices.ro))
# $`Alpha Category`
# [1] "alpha1" "alpha3" "alpha2"
# 
# $`Bravo Category`
# [1] "bravo3" "bravo1" "bravo2"
# 
# $`Charlie Category`
# [1] "charlie2" "charlie3" "charlie1"


# choices as factor
df$choices.fac <- as.factor(df$choices)
levels(df$choices.fac)
# [1] "alpha1"   "alpha2"   "alpha3"   "bravo1"   "bravo2"   "bravo3"   "charlie1" "charlie2"
# [9] "charlie3"

# reorder factor version
ll <- dlply(.data = df, .variables = .(Categories), mutate,
            choices.fac.ro = reorder(choices.fac, ratings))

# reordering takes place _within_ each Category, but on the _full set_ of levels
# $`Alpha Category`
# [1] "alpha1"   "alpha3"   "alpha2"   "bravo1"   "bravo2"   "bravo3"   "charlie1" "charlie2"
# [9] "charlie3"
# This set of levels will be used in ggplot if you start with choices as a factor.
# Hence @Michael Bellhouse comment: "alpha category is ranked but not bravo or charlie"

# $`Bravo Category`
# [1] "bravo3"   "bravo1"   "bravo2"   "alpha1"   "alpha2"   "alpha3"   "charlie1" "charlie2"
# [9] "charlie3"
# 
# $`Charlie Category`
# [1] "charlie2" "charlie3" "charlie1" "alpha1"   "alpha2"   "alpha3"   "bravo1"   "bravo2"  
# [9] "bravo3"

# Because a factor only can have one set of levels,
# the first set is used - $`Alpha Category`
# Thus, relordered within category Alpha only.

【讨论】:

我尝试了第一个问题的代码,但 ggplot 看起来一样 嗯...我更新了运行代码时弹出的图。 ddply 调用前后检查levels(df$choices) 是的,我发现它非常适合您——正是我想要的。经过进一步检查,在我看来,alpha 类别排名但不是 bravo 或 charlie。您介意将您的完整代码复制到我上面的原始代码中,然后完整发布吗? 看来ddply 中的reordering 的问题取决于您是否将“选择”作为一个因素或一个字符来提供它。当我使用data.frame 创建您的df 时,“选择”变成了一个角色。这取决于options 中的stringsAsFactors。我通过ddply 作为一个角色运行它,结果出现了一个看似正确重新排序的因素。但是,如果我将“选择”转换为 before ddply 的因子,则仅重新排序“alpha”类别。奇怪。

以上是关于如何按数字向量的降序显示ggplot2中的条形?的主要内容,如果未能解决你的问题,请参考以下文章

如何按第一位数字的降序对整数数组进行排序? [关闭]

如何按“值”的降序遍历 berkeley-db 数据库?

在ggplot2条形图中对国家名称进行排序[重复]

firebase 和 Ionic 2 上的降序 orderByChild()

按特定键的降序对字典列表进行排序[重复]

c_cpp 按设置位的降序对数组进行排序