问题与ggplot2,geom_bar和position =“dodge”:堆叠有正确的y值,躲闪没有

时间:2012-07-22 21:20:13

标签: r plot ggplot2

我很及时地理解geom_bar()position="dodge"。我试图制作一些说明两组的条形图。最初的数据来自两个独立的数据框。根据{{​​3}},我将数据放入长格式。我的例子:

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值maxes。它们是来自test的数据的总和,其中test2的值显示在顶部的蓝色上。

根据我读过的其他问题,我只需要添加position="dodge"以使其成为并排的情节而非叠加的情节:

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

dodged

它看起来很棒,但请注意新的最大值。看起来它只是从y {值的test的每个名称因子级别获取最大y值。它不再是对它们进行求和。

根据其他一些问题(例如this questionthis one),我也尝试添加group=选项但没有成功(生成与上面相同的躲避情节):

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

我不明白为什么堆叠效果很好而且躲闪不只是将它们并排放在上面而不是顶部。


ETA:我在ggplot google群组中找到了this one,并建议添加alpha=0.5以查看正在发生的事情。并不是ggplot从每个分组中获取最大值;它实际上是为每个值过度绘制了彼此重叠的条形。

似乎在使用position="dodge"时,ggplot预计每x只有一个y。我联系了一位ggplot开发商Winston Chang,对此进行了确认以及询问是否可以更改,因为我没有看到优势。

似乎stat="identity"应该告诉ggplot计算y=val传递的内部aes(),而不是没有stat="identity"且没有传递y值的个别计数。

目前,解决方法似乎是(对于上面的原始df)进行聚合,因此每x只有一个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 个答案:

答案 0 :(得分:17)

我认为问题在于您希望在<{1}}组的值中堆叠,并在num值之间躲避。 查看向条形图添加轮廓时会发生什么情况可能会有所帮助。

num

默认情况下,堆叠了很多条形图 - 除非你有一个大纲,否则你不会看到它们是分开的:

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

如果你躲闪,你会得到徘徊在# Stacked bars ggplot(df, aes(x=factor(names), y=values, fill=factor(num))) + geom_bar(stat="identity", colour="black") 值之间的条形图,但num的每个值中可能有多个条形图:

num

Dodged on 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) 添加为分组变量,它会躲避所有变量:

id

Dodge all bars

我认为你想要的是躲闪和堆叠,但你不能同时做到这两点。 所以最好的事情就是自己总结数据。

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

Summarized beforehand