Следующая функция делает глубокую копию объектов, она охватывает копирование примитива, массивы, а также объект
function mergeDeep (target, source) {
if (typeof target == "object" && typeof source == "object") {
for (const key in source) {
if (source[key] === null && (target[key] === undefined || target[key] === null)) {
target[key] = null;
} else if (source[key] instanceof Array) {
if (!target[key]) target[key] = [];
//concatenate arrays
target[key] = target[key].concat(source[key]);
} else if (typeof source[key] == "object") {
if (!target[key]) target[key] = {};
this.mergeDeep(target[key], source[key]);
} else {
target[key] = source[key];
}
}
}
return target;
}
Ключ с заказом - установить уровни фактора в том порядке, в котором вы хотите. Принудительный коэффициент не требуется; дополнительная информация в упорядоченном коэффициенте не требуется, и если эти данные используются в любой статистической модели, неправильная параметризация может привести к ошибке; полиномиальные контрасты являются неправильными для таких номинальных данных.
## 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)
[/g0]
В самом общем смысле нам просто нужно установить множитель уровни должны быть в желаемом порядке. Если значение не указано, уровни фактора будут отсортированы в алфавитном порядке. Однако есть несколько способов изменить порядок на определенную последовательность в зависимости от ситуации. Например, мы могли бы сделать:
levels(theTable$Position) <- c(...)
и просто перечислить уровни в нужном порядке с правой стороны. Вы также можете указать порядок уровня в вызове с коэффициентом, как указано выше:
theTable$Position <- factor(theTable$Position, levels = c(...))
@GavinSimpson: reorder
является мощным и эффективным решением для этого:
ggplot(theTable,
aes(x=reorder(Position,Position,
function(x)-length(x)))) +
geom_bar()
Я согласен с 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, или с помощью table
.
Я думаю, что уже предоставленные решения чересчур многословны. Более сжатый способ сделать частотный сортированный штрих-код с 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()
Если столбцы диаграммы взяты из числовой переменной, как в приведенной ниже схеме данных, вы можете использовать более простое решение:
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
Когда я нашел эту ветку, это был ответ, который я искал. Надеюсь, это полезно для других.
Вам просто нужно указать столбец Position
как упорядоченный множитель , где уровни упорядочены по их числу:
theTable <- transform( theTable,
Position = ordered(Position, levels = names( sort(-table(Position)))))
(Обратите внимание, что table(Position)
создает частотный счетчик столбца Position
.)
Тогда ваша функция ggplot
покажет полосы в порядке убывания количества. Я не знаю, есть ли опция в geom_bar
, чтобы сделать это без явного создания упорядоченного коэффициента.
reorder()
из библиотеки статистики выполняет ту же задачу.
– Chase
6 March 2011 в 14:44
reorder()
в этом случае? Фактор, требующий переупорядочения, должен быть переупорядочен некоторой функцией самого себя, и я изо всех сил стараюсь найти хороший способ сделать это.
– Gavin Simpson
6 March 2011 в 15:23
with(theTable, reorder(Position, as.character(Position), function(x) sum(duplicated(x))))
- это один путь, а другой with(theTable, reorder(Position, as.character(Position), function(x) as.numeric(table(x))))
, но они так же запутаны ...
– Gavin Simpson
6 March 2011 в 15:39
sort
вместо order
– Prasad Chalasani
6 March 2011 в 15:55
reorder
умело делает. Я согласен с этим вопросом в том, что требуется более активное участие. Извините за путаницу.
– Chase
6 March 2011 в 16:45
В дополнение к 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)
Используя scale_x_discrete (limits = ...)
, чтобы указать порядок баров.
positions <- c("Goalkeeper", "Defense", "Striker")
p <- ggplot(theTable, aes(x = Position)) + scale_x_discrete(limits = positions)
Как и reorder()
в ответе Алекса Брауна, мы могли бы также использовать forcats::fct_reorder()
. Он будет в основном сортировать факторы, указанные в 1-м аргументе, в соответствии со значениями во втором arg после применения указанной функции (по умолчанию = медиана, что мы используем здесь, так как просто одно значение для каждого уровня фактора).
Стыдно, что в вопросе 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')
within
, нет необходимости использоватьtheTable$Position
, и вы можете просто сделатьsort(-table(...))
для уменьшения порядка. – Prasad Chalasani 6 March 2011 в 16:16-
, поскольку гораздо легче получить намерение отdecreasing = TRUE
, чем заметить-
во всей остальной части кода. – Gavin Simpson 6 March 2011 в 16:22-
. – Gavin Simpson 6 March 2011 в 16:39