Измените порядок дискретной шкалы x
Я делаю уклоненную гистограмму с использованием ggplot с дискретной шкалой x, ось x теперь упорядочена в алфавитном порядке, но мне нужно переставить ее так, чтобы она упорядочивалась по значению оси y (т.е. самая высокая полоса будет расположена слева).
Я попробовал порядок или сортировку, но приведу к сортировке оси x, но не к барам соответственно.
Что я сделал неправильно?
Ответы
Ответ 1
Попробуйте вручную установить уровни фактора по оси x. Например:
library(ggplot2)
# Automatic levels
ggplot(mtcars, aes(factor(cyl))) + geom_bar()
![ggplot of the cars dataset with factor levels automatically determined]()
# Manual levels
cyl_table <- table(mtcars$cyl)
cyl_levels <- names(cyl_table)[order(cyl_table)]
mtcars$cyl2 <- factor(mtcars$cyl, levels = cyl_levels)
# Just to be clear, the above line is no different than:
# mtcars$cyl2 <- factor(mtcars$cyl, levels = c("6","4","8"))
# You can manually set the levels in whatever order you please.
ggplot(mtcars, aes(cyl2)) + geom_bar()
![ggplot of the cars dataset with factor levels reordered manually]()
Как отметил Джеймс в своем ответе, reorder
- это идиоматический способ перераспределения уровней факторов.
mtcars$cyl3 <- with(mtcars, reorder(cyl, cyl, function(x) -length(x)))
ggplot(mtcars, aes(cyl3)) + geom_bar()
![ggplot of the cars dataset with factor levels reordered using the reorder function]()
Ответ 2
Лучший способ для меня - использовать вектор с категориями, чтобы мне нужно как параметр limits
для scale_x_discrete
. Я думаю, что это довольно простое и простое решение.
ggplot(mtcars, aes(factor(cyl))) +
geom_bar() +
scale_x_discrete(limits=c(8,4,6))
![enter image description here]()
Ответ 3
Вы можете использовать reorder
:
qplot(reorder(factor(cyl),factor(cyl),length),data=mtcars,geom="bar")
Edit:
Чтобы иметь самый высокий бар слева, вы должны использовать немного kludge:
qplot(reorder(factor(cyl),factor(cyl),function(x) length(x)*-1),
data=mtcars,geom="bar")
Я ожидаю, что это также будет иметь отрицательные высоты, но это не так, поэтому он работает!
Ответ 4
Хэдли разрабатывает пакет под названием forcats
. Этот пакет делает задачу намного проще. Вы можете использовать fct_infreq()
, когда вы хотите изменить порядок оси x на частоту фактора. В случае примера mtcars
в этом сообщении вы хотите переупорядочить уровни cyl
по частоте каждого уровня. Уровень, который чаще всего остается на левой стороне. Все, что вам нужно, это fct_infreq()
.
library(ggplot2)
library(forcats)
ggplot(mtcars, aes(fct_infreq(factor(cyl)))) +
geom_bar() +
labs(x = "cyl")
Если вы хотите пойти наоборот, вы можете использовать fct_rev()
вместе с fct_infreq()
.
ggplot(mtcars, aes(fct_rev(fct_infreq(factor(cyl))))) +
geom_bar() +
labs(x = "cyl")
![введите описание изображения здесь]()
Ответ 5
Я понимаю, что это старо, но, возможно, эта функция, которую я создал, полезна кому-то там:
order_axis<-function(data, axis, column)
{
# for interactivity with ggplot2
arguments <- as.list(match.call())
col <- eval(arguments$column, data)
ax <- eval(arguments$axis, data)
# evaluated factors
a<-reorder(with(data, ax),
with(data, col))
#new_data
df<-cbind.data.frame(data)
# define new var
within(df,
do.call("<-",list(paste0(as.character(arguments$axis),"_o"), a)))
}
Теперь, с помощью этой функции, вы можете интерактивно рисовать с помощью ggplot2, например:
ggplot(order_axis(df, AXIS_X, COLUMN_Y),
aes(x = AXIS_X_o, y = COLUMN_Y)) +
geom_bar(stat = "identity")
Как видно, функция order_axis
создает еще один фрейм данных с новым столбцом с именем то же самое, но с _o
в конце. Этот новый столбец имеет уровни в порядке возрастания, поэтому ggplot2 автоматически закладывается в этом порядке.
Это несколько ограничено (работает только для символьных или факторных и числовых комбинаций столбцов и в порядке возрастания), но я все же считаю это очень полезным для построения графика на ходу.