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