Заменить бары в ggplot2 с процентами [дубликат]

Следующая функция делает глубокую копию объектов, она охватывает копирование примитива, массивы, а также объект

 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;
}
233
задан Roland Ewald 8 October 2016 в 17:32
поделиться

10 ответов

Ключ с заказом - установить уровни фактора в том порядке, в котором вы хотите. Принудительный коэффициент не требуется; дополнительная информация в упорядоченном коэффициенте не требуется, и если эти данные используются в любой статистической модели, неправильная параметризация может привести к ошибке; полиномиальные контрасты являются неправильными для таких номинальных данных.

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

barplot figure [/g0]

В самом общем смысле нам просто нужно установить множитель уровни должны быть в желаемом порядке. Если значение не указано, уровни фактора будут отсортированы в алфавитном порядке. Однако есть несколько способов изменить порядок на определенную последовательность в зависимости от ситуации. Например, мы могли бы сделать:

levels(theTable$Position) <- c(...)

и просто перечислить уровни в нужном порядке с правой стороны. Вы также можете указать порядок уровня в вызове с коэффициентом, как указано выше:

theTable$Position <- factor(theTable$Position, levels = c(...))
166
ответ дан MrFlick 20 August 2018 в 12:12
поделиться
  • 1
    @Gavin: 2 упрощения: поскольку вы уже используете within, нет необходимости использовать theTable$Position, и вы можете просто сделать sort(-table(...)) для уменьшения порядка. – Prasad Chalasani 6 March 2011 в 16:16
  • 2
    @Prasad the first был оставшимся от тестирования, поэтому спасибо, что указали это. В последнем случае я предпочитаю явно запрашивать обратный сортировку, чем используемый вами -, поскольку гораздо легче получить намерение от decreasing = TRUE, чем заметить - во всей остальной части кода. – Gavin Simpson 6 March 2011 в 16:22
  • 3
    @Gavin ok Я понимаю, что вы имеете в виду – Prasad Chalasani 6 March 2011 в 16:34
  • 4
    @Prasad - это просто личное предпочтение после многих лет написания сценариев анализа в моей работе, что мне приходилось иногда пересматривать и проклинать себя за то, что я не писал более четкий код. Нет ничего плохого в использовании -. – Gavin Simpson 6 March 2011 в 16:39
  • 5
    @Gavin, конечно, ваш подход имеет смысл. Я часто выбираю более короткий синтаксис по ясности, но я знаю, что он может иногда укусить меня! – Prasad Chalasani 6 March 2011 в 23:22

@GavinSimpson: reorder является мощным и эффективным решением для этого:

ggplot(theTable,
       aes(x=reorder(Position,Position,
                     function(x)-length(x)))) +
       geom_bar()
169
ответ дан Alex Brown 20 August 2018 в 12:12
поделиться
  • 1
    Действительно +1, и особенно в этом случае, когда существует логический порядок, который мы можем использовать численно. Если мы рассматриваем произвольный порядок категорий и не хотим алфавитную форму, то просто (проще?) Указать уровни непосредственно, как показано. – Gavin Simpson 14 June 2012 в 11:05
  • 2
    Такое чистое решение. Спасибо. – Gabriel J. Odom 26 April 2018 в 19:41

Я согласен с 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.

13
ответ дан Deli 20 August 2018 в 12:12
поделиться

Я думаю, что уже предоставленные решения чересчур многословны. Более сжатый способ сделать частотный сортированный штрих-код с 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()
65
ответ дан Holger Brandl 20 August 2018 в 12:12
поделиться

Если столбцы диаграммы взяты из числовой переменной, как в приведенной ниже схеме данных, вы можете использовать более простое решение:

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

Когда я нашел эту ветку, это был ответ, который я искал. Надеюсь, это полезно для других.

2
ответ дан JColares 20 August 2018 в 12:12
поделиться

Вам просто нужно указать столбец Position как упорядоченный множитель , где уровни упорядочены по их числу:

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

(Обратите внимание, что table(Position) создает частотный счетчик столбца Position.)

Тогда ваша функция ggplot покажет полосы в порядке убывания количества. Я не знаю, есть ли опция в geom_bar, чтобы сделать это без явного создания упорядоченного коэффициента.

16
ответ дан Prasad Chalasani 20 August 2018 в 12:12
поделиться
  • 1
    Я не полностью разбирал ваш код там, но я уверен, что reorder() из библиотеки статистики выполняет ту же задачу. – Chase 6 March 2011 в 14:44
  • 2
    @Chase, как вы предлагаете использовать reorder() в этом случае? Фактор, требующий переупорядочения, должен быть переупорядочен некоторой функцией самого себя, и я изо всех сил стараюсь найти хороший способ сделать это. – Gavin Simpson 6 March 2011 в 15:23
  • 3
    ok, 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
  • 4
    Я немного упростил ответ, чтобы использовать sort вместо order – Prasad Chalasani 6 March 2011 в 15:55
  • 5
    @Gavin - возможно, я неправильно понял исходный код Прасад (у меня нет R на этой машине, чтобы проверить ...), но выглядело так, как будто он перестраивал категории по частоте, что 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)             

8
ответ дан Robert McDonald 20 August 2018 в 12:12
поделиться

Используя scale_x_discrete (limits = ...), чтобы указать порядок баров.

positions <- c("Goalkeeper", "Defense", "Striker")
p <- ggplot(theTable, aes(x = Position)) + scale_x_discrete(limits = positions)
108
ответ дан tonytonov 20 August 2018 в 12:12
поделиться
  • 1
    Ваше решение наиболее подходит для моей ситуации, так как я хочу запрограммировать на график, когда x является произвольным столбцом, выраженным переменной в data.frame. Другим предложениям было бы сложнее выразить расположение порядка x выражением с переменной. Благодаря! Если есть интерес, я могу поделиться своим решением, используя ваше предложение. Еще одна проблема, добавив scale_x_discrete (limits = ...), я обнаружил, что в правой части диаграммы имеется пустое пространство, такое же, как и в виде диаграммы. Как я могу избавиться от пустого пространства? Поскольку это не служит никакой цели. – Yu Shen 28 April 2015 в 01:04
  • 2
    Это кажется необходимым для упорядочения гистограмм – geotheory 4 August 2015 в 09:50
  • 3
    QIBIN: Ничего себе ... другие ответы здесь работают, но ваш ответ на первый взгляд кажется не только самым кратким и изящным, но наиболее очевидным, когда вы думаете изнутри рамки ggplot. Спасибо. – Dan Nguyen 10 September 2015 в 13:53
  • 4
    Когда я пробовал это решение, по моим данным, он не отображал NA. Есть ли способ использовать это решение и иметь его график NA? – user2460499 25 May 2017 в 18:13

Как и 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')

13
ответ дан user2739472 20 August 2018 в 12:12
поделиться
17
ответ дан Deli 31 October 2018 в 09:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: