我正在尝试制作一个条形图,其中最大的条最接近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轴,守门员一个,最后是前锋一个。 感谢
答案 0 :(得分:193)
@GavinSimpson:reorder
是一个强大而有效的解决方案:
ggplot(theTable,
aes(x=reorder(Position,Position,
function(x)-length(x)))) +
geom_bar()
答案 1 :(得分:187)
订购的关键是按所需顺序设置系数的级别。不需要有序因子;有序因子中的额外信息不是必需的,如果在任何统计模型中使用这些数据,可能会导致错误的参数化 - 多项式对比不适合这样的标称数据。
## 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)
在最一般意义上,我们只需要将因子水平设置为所需的顺序。如果未指定,则因子的级别将按字母顺序排序。您也可以在上面调用因子中指定级别顺序,也可以采用其他方式。
theTable$Position <- factor(theTable$Position, levels = c(...))
答案 2 :(得分:132)
使用scale_x_discrete (limits = ...)
指定条形的顺序。
positions <- c("Goalkeeper", "Defense", "Striker")
p <- ggplot(theTable, aes(x = Position)) + scale_x_discrete(limits = positions)
答案 3 :(得分:77)
我认为已经提供的解决方案过于冗长。使用ggplot进行频率排序条形图的更简洁方法是
ggplot(theTable, aes(x=reorder(Position, -table(Position)[Position]))) + geom_bar()
它类似于亚历克斯·布朗所建议的,但有点短,无需任何函数定义。
<强>更新强>
我认为我现在的旧解决方案很不错,但现在我宁愿使用forcats::fct_infreq
来按频率对因子级别进行排序:
require(forcats)
ggplot(theTable, aes(fct_infreq(Position))) + geom_bar()
答案 4 :(得分:22)
与Alex Brown的答案中的reorder()
一样,我们也可以使用forcats::fct_reorder()
。它将基本上对第一个arg中指定的因子进行排序,根据应用指定函数后的第二个arg中的值(默认值=中位数,这是我们在这里使用的每个因子级别只有一个值)。
令人遗憾的是,在OP的问题中,所需的顺序也是按字母顺序排列的,因为这是创建因子时的默认排序顺序,因此将隐藏此功能实际执行的操作。为了更清楚,我将取代&#34;守门员&#34;与&#34; Zoalkeeper&#34;。
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')
答案 5 :(得分:21)
基于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
答案 6 :(得分:17)
您只需将Position
列指定为有序因子,其中的等级按其计数排序:
theTable <- transform( theTable,
Position = ordered(Position, levels = names( sort(-table(Position)))))
(请注意,table(Position)
会产生Position
列的频率计数。)
然后,您的ggplot
函数将按计数递减顺序显示条形。
我不知道geom_bar
中是否有选项可以在不必明确创建有序因子的情况下执行此操作。
答案 7 :(得分:14)
除了forcats :: fct_infreq之外,还提到了 @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)
答案 8 :(得分:10)
我同意扎克认为在dplyr内计算是最好的解决方案。我发现这是最短的版本:
dplyr::count(theTable, Position) %>%
arrange(-n) %>%
mutate(Position = factor(Position, Position)) %>%
ggplot(aes(x=Position, y=n)) + geom_bar(stat="identity")
这也比预先重新排序因子级别快得多,因为计数是在dplyr中完成的,而不是在ggplot中或使用table
。
答案 9 :(得分:9)
如果图表列来自下面的数据框中的数字变量,则可以使用更简单的解决方案:
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
当我找到该线程时,这就是我想要的答案。希望对其他人有用。
答案 10 :(得分:3)
因为我们只查看单个变量(“位置”)的分布,而不是查看两个变量之间的关系,所以也许{ 3}}将是更合适的图形。 ggplot具有histogram,可以轻松实现:
ggplot(theTable, aes(x = Position)) + geom_histogram(stat="count")
使用geom_histogram():
我认为)有点古怪,因为它对连续数据和离散数据的处理方式不同。
对于连续数据,您可以仅使用不带参数的geom_histogram(。 例如,如果我们添加数字矢量“分数” ...
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
并在“分数”变量上使用geom_histogram()...
ggplot(theTable, aes(x = Score)) + geom_histogram()
对于像“位置”这样的离散数据,我们必须指定一个通过美学计算的统计量,以使用stat = "count"
给出钢筋高度的y值:
ggplot(theTable, aes(x = Position)) + geom_histogram(stat = "count")
注意:令人困惑和困惑的是,您也可以使用stat = "count"
来获取连续数据,我认为它提供了一个更加美观的图形。
ggplot(theTable, aes(x = Score)) + geom_histogram(stat = "count")
答案 11 :(得分:3)
我感到非常烦人的是,ggplot2
没有为此提供“自动”解决方案。这就是为什么我在ggcharts
中创建了bar_chart()
函数的原因。
ggcharts::bar_chart(theTable, Position)
默认情况下,bar_chart()
对条形进行排序并显示水平图。要更改该设置horizontal = FALSE
。此外,bar_chart()
消除了条形图和轴之间难看的“间隙”。
答案 12 :(得分:1)
另一种使用 reorder 排序因子水平的方法。基于计数按升序(n)或降序(-n)。与使用fct_reorder
软件包中的forcats
的人非常相似:
降序
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))
答案 13 :(得分:-1)
您可以简单地使用以下代码:
ggplot(yourdatasetname, aes(Position, fill = Name)) +
geom_bar(col = "black", size = 2)