我要做一个柱状图,其中最大的柱状图离y轴最近,最短的柱状图离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)

但是图表显示的是门将栏,然后是防守栏,最后是前锋栏。我希望图表的顺序是,防守条最靠近y轴,守门员条,最后是前锋条。 谢谢


当前回答

就像Alex Brown回答中的reorder()一样,我们也可以使用forcats::fct_reorder()。它基本上会对第一个参数中指定的因子进行排序,根据应用指定函数后第二个参数中的值(default = median,这是我们在这里使用的,因为每个因子级别只有一个值)。

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

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')

其他回答

另一种方法是使用重新排序来排列因子的级别。根据计数的升序(n)或降序(-n)。非常类似于使用forcats包中的fct_reorder:

降序排列

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

升序排序 df % > % 数(位置)% > % ggplot(aes(x = reorder(Position, n), y = n)) + Geom_bar (stat = 'identity') + xlab(“位置”) 数据帧: df <- structure(list(Position = structure(c(3L, 3L, 1L, 1L, 1L, 2L), .Label = c("防御", "前锋","Zoalkeeper"), class = "factor"), Name =结构(c(2L, 1 l, 3 l 5 l 4 l, 6 l), .Label = c(“弗兰克”,“詹姆斯”,“琼”,“约翰”, "Steve", "Tim"), class = "factor")), class = "data.frame", row.names = c(NA, 6 l))

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

ggcharts::bar_chart(theTable, Position)

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

你只需要指定Position列为一个有序因子,其中级别是按它们的计数排序的:

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

(请注意,表(Position)产生了Position列的频率计数。)

然后,您的ggplot函数将以计数递减的顺序显示条形图。 我不知道在geom_bar中是否有一个选项可以在不显式地创建有序因子的情况下做到这一点。

由于我们只关注单个变量(“位置”)的分布,而不是两个变量之间的关系,那么直方图可能是更合适的图形。Ggplot有geom_histogram(),这使得它很容易:

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

使用geom_histogram ():

我认为geom_histogram()有点古怪,因为它对待连续数据和离散数据是不同的。

对于连续数据,可以只使用不带参数的geom_histogram()。 例如,如果我们添加一个数字向量“Score”……

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

然后在“Score”变量上使用geom_histogram()…

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

对于像“Position”这样的离散数据,我们必须指定一个由美学计算出来的统计数据,使用stat = "count"来给出条形高度的y值:

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

注意:奇怪且令人困惑的是,你也可以使用stat = "count"来表示连续的数据,我认为它提供了一个更美观的图形。

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

编辑:对DebanjanB的有用建议的扩展回答。

library(ggplot2)
library(magrittr)

dd <- tibble::tribble(
    ~Name,    ~Position,
  "James", "Goalkeeper",
  "Frank", "Goalkeeper",
   "Jean",    "Defense",
   "John",    "Defense",
  "Steve",    "Defense",
    "Tim",    "Striker"
  )


dd %>% ggplot(aes(x = forcats::fct_infreq(Position))) + geom_bar()

于2022-08-30使用reprex v2.0.2创建