20

我有相当的时间理解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")

堆积图

特别要注意 y 值的最大值。它们是来自顶部蓝色显示test的值的数据总和。test2

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

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

躲过了

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

根据其他一些问题(比如这个这个,我也尝试添加group=选项但没有成功(产生与上面相同的躲避图):

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

我不明白为什么堆叠的效果很好,而躲避的不只是将它们并排而不是放在上面。


ETA:最近在 ggplot 谷歌组上发现了一个关于此的问题,并建议添加alpha=0.5以查看发生了什么。并不是 ggplot 从每个分组中获取最大值;它实际上是在每个值的顶部绘制条形图。

似乎在使用时position="dodge",ggplot 预计每个 x 只需要一个 y。我联系了 ggplot 开发人员 Winston Chang 以确认并询问是否可以更改,因为我没有看到优势。

似乎stat="identity"应该告诉 ggplot 计算y=val内部传递的值,而不是在没有传递任何 y 值aes()的情况下发生的单个计数。stat="identity"

目前,解决方法似乎是(对于上面的原始 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

正确的

4

1 回答 1

24

我认为问题在于您想在组的值堆叠,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
ggplot(df, aes(x=factor(names), y=values, fill=factor(num))) + 
  geom_bar(stat="identity", colour="black")

堆叠条

如果你躲避,你会得到在 的值之间躲避的条形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)

躲过 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)

躲避所有酒吧

我认为你想要的是躲避和堆叠,但你不能两者都做。所以最好的办法是自己总结数据。

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

事前总结

于 2012-07-23T21:24:31.203 回答