Вопрос по plot, r, ggplot2 – Проблема с ggplot2, geom_bar и position = «dodge»: у стека есть правильные значения y, у dodged нет

14

У меня достаточно времени для пониманияgeom_bar() а такжеposition="dodge", Я пытался сделать несколько гистограмм, иллюстрирующих две группы. Первоначально данные были из двух отдельных фреймов данных. вэтот вопросЯ поставил свои данные в длинном формате. Мой пример:

test <- data.frame(names=rep(c("A","B","C"), 5), values=1:15)
test2 <- data.frame(names=c("A","B","C"), values=5:7)

df <- data.frame(names=c(paste(test$names), paste(test2$names)), num=c(rep(1, 
nrow(test)), rep(2, nrow(test2))), values=c(test$values, test2$values))

Я использую этот пример, так как он аналогичен примеру расходов против бюджета. Расходы имеют много строк вnames уровень фактора, тогда как бюджет имеет только один (одна сумма бюджета на категорию).

Для гистограммы с накоплением это прекрасно работает:

ggplot(df, aes(x=factor(names), y=values, fill=factor(num))) +
geom_bar(stat="identity")

stacked plot

В частности, обратите внимание на максимальные значения y. Это суммы данных изtest со значениямиtest2 показано на синем сверху.

На основании других вопросов, которые я прочитал, мне просто нужно добавитьposition="dodge" чтобы сделать его соседним, а не сложным:

ggplot(df, aes(x=factor(names), y=values, fill=factor(num))) + 
geom_bar(stat="identity", position="dodge")

dodged

Это выглядит великолепно, но обратите внимание на новые значения max y. Кажется, что он просто берет максимальное значение y из каждого уровня фактора имен изtest для значения у. Это больше не суммирует их.

На некоторые другие вопросы (например,этот а такжеэтотЯ также попытался добавитьgroup= опция без успеха (выдает тот же сюжет с уклонением, что и выше):

ggplot(df, aes(x=factor(names), y=values, fill=factor(num), group=factor(num))) +
geom_bar(stat="identity", position="dodge")

Я не понимаю, почему сложенный пакет работает отлично, а уклоненный объект не просто помещает их рядом, а не сверху.

ETA: Я нашелнедавний вопрос об этом в ggplot google group с предложением добавитьalpha=0.5 чтобы увидеть, что происходит. Это не означает, что ggplot принимает максимальное значение из каждой группировки; на самом деле это избыточное построение столбцов друг над другом для каждого значения.

Кажется, что при использованииposition="dodge", ggplot ожидает только один y на x. Я связался с Уинстоном Чангом, разработчиком ggplot, чтобы подтвердить, а также узнать, можно ли это изменить, так как я не вижу преимущества.

Кажется, чтоstat="identity" должен сказать ggplot подсчитатьy=val прошло внутриaes() вместо отдельных подсчетов, что происходит безstat="identity" и при передаче нет значения у.

На данный момент обходной путь, по-видимому, (для первоначального df выше) агрегирует, так что на х имеется только один y:

df2 <- aggregate(df$values, by=list(df$names, df$num), FUN=sum)
p <- ggplot(df2, aes(x=Group.1, y=x, fill=factor(Group.2)))
p <- p + geom_bar(stat="identity", position="dodge")
p

correct

Ваш Ответ

1   ответ
17

Я думаю, что проблема в том, что вы хотите сложитьwithin значенияnum группа и увернутьсяbetween значенияnum. It might help to look at what happens when you add an outline to the bars.

library(ggplot2)
set.seed(123)
df <- data.frame(
  id     = 1:18,
  names  = rep(LETTERS[1:3], 6),
  num    = c(rep(1, 15), rep(2, 3)),
  values = sample(1:10, 18, replace=TRUE)
)

По умолчанию много столбцов сложено - вы просто не увидите, что они разделены, если у вас нет структуры:

# Stacked bars
ggplot(df, aes(x=factor(names), y=values, fill=factor(num))) + 
  geom_bar(stat="identity", colour="black")

Stacked bars

Если вы уклоняетесь, вы получаете бары, которые уклоняются между значениямиnum, но в каждом значении может быть несколько баровnum:

# Dodged on 'num', but some overplotted bars
ggplot(df, aes(x=factor(names), y=values, fill=factor(num))) + 
  geom_bar(stat="identity", colour="black", position="dodge", alpha=0.1)

Dodged on num

Если вы также добавитеid как группирующий вариант, он уклонится от всех:

# Dodging with unique 'id' as the grouping var
ggplot(df, aes(x=factor(names), y=values, fill=factor(num), group=factor(id))) + 
  geom_bar(stat="identity", colour="black", position="dodge", alpha=0.1)

Dodge all bars

Я думаю, что вы хотите уклоняться и складываться, но вы не можете делать и то, и другое. Так что лучше всего подвести итоги самостоятельно.

library(plyr)
df2 <- ddply(df, c("names", "num"), summarise, values = sum(values))

ggplot(df2, aes(x=factor(names), y=values, fill=factor(num))) + 
  geom_bar(stat="identity", colour="black", position="dodge")

Summarized beforehand

Спасибо за объяснение. Агрегирование не имеет большого значения, и теперь я знаю, что мне это нужно, что является большим шагом от простого замешательства :) Hendy
Понял. Было бы очень полезно, чтобы вы указали, что я на самом деле прошу уклоняться и складывать. Одно замечание: когда не используетсяstat="identity" (таким образом, по сути, составление гистограммы), не является "составлением стека" индивидуальный счет при уклонении от некоторых других характеристик? Тем не менее, я согласен с ответом, что это так, как он работает в данный момент. Я думал, что делал что-то не так в своем коде! Hendy
geom_bar может немного сбивать с толку, потому что он используется для двух разных целей: иногда он используется для построения графиков значений y, которые вы предоставляете, а иногда он подсчитывает количество случаев в каждом и использует это значение как значение y (сstat="bin"). Последнее поведение по умолчанию (вы можете увидеть это сggplot(df, aes(x=factor(names), fill=factor(num))) + geom_bar(colour="black") ). В этом случае «укладка» не совсем то же самое - это краткое изложениеstatв то время как обычная укладкаposition adjustment, Это происходит на разных этапах конвейера ggplot.

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