R ggplot2条形图中的顺序条

R ggplot2条形图中的顺序条,r,ggplot2,r-faq,R,Ggplot2,R Faq,我试图制作一个条形图,其中最大的条形图最靠近y轴,最短的条形图最远。这有点像我的桌子 Name Position 1 James Goalkeeper 2 Frank Goalkeeper 3 Jean Defense 4 Steve Defense 5 John Defense 6 Tim Striker 所以我试图建立一个条形图,根据位置显示球员的数量 p <- ggplot(theTable, aes(x = Position

我试图制作一个条形图,其中最大的条形图最靠近y轴,最短的条形图最远。这有点像我的桌子

    Name   Position
1   James  Goalkeeper
2   Frank  Goalkeeper
3   Jean   Defense
4   Steve  Defense
5   John   Defense
6   Tim    Striker
所以我试图建立一个条形图,根据位置显示球员的数量

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

p您只需将
位置
列指定为有序因子,其中级别按计数排序:

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

表格排序的关键是按您想要的顺序设置因子的级别。不需要有序因子;有序因子中的额外信息是不必要的,如果在任何统计模型中使用这些数据,可能会导致错误的参数化-多项式对比度不适合这样的标称数据

## 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)
##按照我们想要的顺序设置级别

表@GavinSimpson:
重新排序
是一个强大而有效的解决方案:

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

使用
scale\u x\u discrete(limits=…)
指定条形图的顺序

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

位置我认为已经提供的解决方案过于冗长。使用ggplot进行频率排序条形图的更简洁的方法是

ggplot(theTable, aes(x=reorder(Position, -table(Position)[Position]))) + geom_bar()
它与Alex Brown的建议类似,但略短一些,并且在没有任何同名函数定义的情况下工作

更新

我认为我以前的解决方案当时很好,但现在我宁愿使用
forcats::fct_informeq
,它是按频率排序因子级别:

require(forcats)

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

基于dplyr的简单因子重新排序可以解决此问题:

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中计数是最好的解决方案。我发现这是最短的版本:

dplyr::count(theTable, Position) %>%
          arrange(-n) %>%
          mutate(Position = factor(Position, Position)) %>%
          ggplot(aes(x=Position, y=n)) + geom_bar(stat="identity")
这也将大大快于预先对因子水平进行重新排序,因为计数是在dplyr中进行的,而不是在ggplot中,或者使用
表格
重新排序()
在Alex Brown的回答中,我们也可以使用
forcats::fct\u重新排序()
。它基本上会根据应用指定函数后第二个参数中的值对第一个参数中指定的因子进行排序(默认值=中值,我们在这里使用的是每个因子级别只有一个值)

遗憾的是,在OP的问题中,所需的顺序也是按字母顺序排列的,因为这是创建因子时的默认排序顺序,因此将隐藏此函数实际执行的操作。更清楚地说,我将用“Zoalkeeper”替换“守门员”

库(tidyverse)
图书馆(供猫用)
表格%
计数(位置)%>%
变异(位置=fct_重新排序(位置,n,.desc=真))%>%
ggplot(aes(x=位置,y=n))+geom_条(stat='identity')

除了forcats::fct_inforeq,由 @HolgerBrandl,有一个forcats::fct_rev,它颠倒了因子顺序

theTable <- data.frame(
    Position= 
        c("Zoalkeeper", "Zoalkeeper", "Defense",
          "Defense", "Defense", "Striker"),
    Name=c("James", "Frank","Jean",
           "Steve","John", "Tim"))

p1 <- ggplot(theTable, aes(x = Position)) + geom_bar()
p2 <- ggplot(theTable, aes(x = fct_infreq(Position))) + geom_bar()
p3 <- ggplot(theTable, aes(x = fct_rev(fct_infreq(Position)))) + geom_bar()

gridExtra::grid.arrange(p1, p2, p3, nrow=3)             

表格如果图表列来自以下数据框中的数字变量,则可以使用更简单的解决方案:

ggplot(df, aes(x = reorder(Colors, -Qty, sum), y = Qty)) 
+ geom_bar(stat = "identity")  
排序变量(-Qty)前的减号控制排序方向(升序/降序)

以下是一些测试数据:

df <- data.frame(Colors = c("Green","Yellow","Blue","Red","Yellow","Blue"),  
                 Qty = c(7,4,5,1,3,6)
                )

**Sample data:**
  Colors Qty
1  Green   7
2 Yellow   4
3   Blue   5
4    Red   1
5 Yellow   3
6   Blue   6

df另一种选择是使用重新排序对因子的级别进行排序。根据计数以升序(n)或降序(-n)排列。与使用
forcats
软件包中的
fct\u重新排序
非常相似:

降序

df %>%
  count(Position) %>%
  ggplot(aes(x = reorder(Position, -n), y = n)) +
  geom_bar(stat = 'identity') +
  xlab("Position")
df %>%
  count(Position) %>%
  ggplot(aes(x = reorder(Position, n), y = n)) +
  geom_bar(stat = 'identity') +
  xlab("Position")
升序

df %>%
  count(Position) %>%
  ggplot(aes(x = reorder(Position, -n), y = n)) +
  geom_bar(stat = 'identity') +
  xlab("Position")
df %>%
  count(Position) %>%
  ggplot(aes(x = reorder(Position, n), y = n)) +
  geom_bar(stat = 'identity') +
  xlab("Position")
数据帧:

df <- structure(list(Position = structure(c(3L, 3L, 1L, 1L, 1L, 2L), .Label = c("Defense", 
"Striker", "Zoalkeeper"), class = "factor"), Name = structure(c(2L, 
1L, 3L, 5L, 4L, 6L), .Label = c("Frank", "James", "Jean", "John", 
"Steve", "Tim"), class = "factor")), class = "data.frame", row.names = c(NA, 
-6L))

df因为我们只关注单个变量(“位置”)的分布,而不是两个变量之间的关系,那么a可能是更合适的图形。ggplot有一个简单的功能:

ggplot(theTable, aes(x = Position)) + geom_histogram(stat="count")

使用几何直方图():

我认为)有点奇怪,因为它以不同的方式处理连续数据和离散数据

对于连续数据,可以不带参数直接使用。 例如,如果我们加入一个数字向量“Score”

并对“Score”变量使用geom_histogram()

ggplot(theTable, aes(x = Score)) + geom_histogram()

对于离散数据如“位置”,我们必须指定由美学计算的统计数据,以便使用
stat=“count”
给出条形高度的y值:

注意:奇怪且令人困惑的是,您还可以对连续数据使用
stat=“count”
,我认为它提供了一个更美观的图形

ggplot(theTable, aes(x = Score)) + geom_histogram(stat = "count")


编辑:针对“的有用建议”的扩展答案。

我发现,
ggplot2
没有为此提供“自动”解决方案,这让我非常恼火。这就是为什么我在中创建了
条形图()
函数

ggcharts::条形图(表格,位置)


默认情况下,
条形图()
对条形图进行排序并显示水平图。更改该设置
水平=FALSE
。此外,
条形图()
消除了条形图和轴之间难看的“间隙”。

您可以简单地使用以下代码:

ggplot(yourdatasetname, aes(Position, fill = Name)) + 
     geom_bar(col = "black", size = 2)

我没有完全解析上面的代码,但我很确定统计库中的
reorder()
完成了相同的任务。@Chase在这种情况下,您建议如何使用
reorder()
?需要重新排序的因子需要通过自身的某个函数重新排序,我正在努力寻找一种好的方法。好的,
使用(表格,重新排序(位置,as.character(Position),函数(x)sum(duplicated(x))
是一种方法,而另一种
使用(表格,重新排序(Position,as.character(Position),函数(x)as.numeric)(表(x))
但这些都是复杂的…我稍微简化了答案,使用
排序
,而不是
顺序
@Gavin-也许我误解了Prasad的原始代码(我没有在这台机器上测试R…)但他似乎是在根据频率对类别进行重新排序,这是
reorder
所擅长的。对于这个问题,我同意需要更多的参与
ggplot(theTable, aes(x = Score)) + geom_histogram(stat = "count")
ggplot(yourdatasetname, aes(Position, fill = Name)) + 
     geom_bar(col = "black", size = 2)