在ggplot2条形图中订单栏

我正在试图制作一个条形图,其中最大的条形将与y轴最接近,最短的条形将最远。 所以这就像我的桌子一样

Name Position 1 James Goalkeeper 2 Frank Goalkeeper 3 Jean Defense 4 Steve Defense 5 John Defense 6 Tim Striker 

所以我正在试图build立一个条形图来显示根据位置的玩家数量

 p <- ggplot(theTable, aes(x = Position)) + geom_bar(binwidth = 1) 

但是图中先显示守门员先防守吧,最后是前锋一号。 我想要图表的sorting,使防守栏最接近y轴,守门员,最后是前锋之一。 谢谢

订购的关键是按照你想要的顺序设置因子的水平。 一个有序的因素是不需要的; 有序因子中的额外信息是不必要的,如果这些数据在任何统计模型中被使用,那么可能导致错误的参数化 – 多项式对比对于这样的名义数据是不正确的。

 ## set the levels in order we want theTable <- within(theTable, Position <- factor(Position, levels=names(sort(table(Position), decreasing=TRUE)))) ## plot ggplot(theTable,aes(x=Position))+geom_bar(binwidth=1) 

barplot图

从最一般意义上讲,我们只需要将因子水平设置为所需的顺序即可。 根据情况,有多种方法可以做到这一点。 例如,我们可以这样做:

 levels(theTable$Position) <- c(...) 

并在右侧列出所需的顺序。 您也可以在呼叫中指定级别顺序,如上所示:

 theTable$Position <- factor(theTable$Position, levels = c(...)) 

@GavinSimpson: reorder是一个强大而有效的解决scheme:

 ggplot(theTable, aes(x=reorder(Position,Position, function(x)-length(x)))) + geom_bar() 

使用scale_x_discrete (limits = ...)来指定条的顺序。

 positions <- c("Goalkeeper", "Defense", "Striker") p <- ggplot(theTable, aes(x = Position)) + scale_x_discrete(limits = positions) 

我认为已经提供的解决scheme过于冗长。 使用ggplot进行频率sorting的barplot的更简洁的方法是

 ggplot(theTable, aes(x=reorder(Position, -table(Position)[Position]))) + geom_bar() 

这与Alex Brown的build议类似,但稍微短一点,没有任何有意义的function定义。

更新

我认为我的旧解决scheme在当时是好的,但是现在我宁愿使用forcats::fct_infreq ,它是按频率sorting因子级别:

 require(forcats) ggplot(theTable, aes(fct_infreq(Position))) + geom_bar() 

您只需要指定“ Position列作为sorting因子 ,其中的级别按其计数sorting:

 theTable <- transform( theTable, Position = ordered(Position, levels = names( sort(-table(Position))))) 

(请注意, table(Position)生成Position列的频率计数。)

然后你的ggplot函数会按照count的顺序显示这些条。 我不知道在geom_bar是否有一个选项来做到这一点,而不必明确创build一个有序的因素。

像Alex Brown的回答中的reorder()一样,我们也可以使用forcats::fct_reorder() 。 它将根据第二个参数在应用指定函数后的值(默认=中位数,这里我们使用的每个因子水平只有一个值)对第一个参数中指定的因子进行基本sorting。

在OP的问题中,所要求的顺序也是按字母顺序的,因为这是创build因子时的默认sorting顺序,所以会隐藏这个函数实际上在做什么。 为了更清楚,我将用“Zoalkeeper”replace“守门员”。

 library(tidyverse) library(forcats) theTable <- data.frame( Name = c('James', 'Frank', 'Jean', 'Steve', 'John', 'Tim'), Position = c('Zoalkeeper', 'Zoalkeeper', 'Defense', 'Defense', 'Defense', 'Striker')) theTable %>% count(Position) %>% mutate(Position = fct_reorder(Position, n, .desc = TRUE)) %>% ggplot(aes(x = Position, y = n)) + geom_bar(stat = 'identity') 

在这里输入图像描述

一个简单的基于dplyr的因素重新sorting可以解决这个问题:

 library(dplyr) #reorder the table and reset the factor to that ordering theTable %>% group_by(Position) %>% # calculate the counts summarize(counts = n()) %>% arrange(-counts) %>% # sort by counts mutate(Position = factor(Position, Position)) %>% # reset factor ggplot(aes(x=Position, y=counts)) + # plot geom_bar(stat="identity") # plot histogram 

我同意zach在dplyr内计数是最好的解决scheme。 我发现这是最短的版本:

 dplyr::count(theTable, Position) %>% arrange(-n) %>% mutate(Position = factor(Position, Position)) %>% ggplot(aes(x=Position, y=n)) + geom_bar(stat="identity") 

这也会比重新sorting因子水平快得多,因为计数是在dplyr而不是ggplot或使用table