我有足够的时间来理解geom_bar()position="dodge"。我试图制作一些说明两组的条形图。最初,数据来自两个单独的数据帧。根据this question,我将数据以长格式存储。我的例子:

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




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

对于其他一些问题(例如this onethis one,我也尝试添加group=选项但未成功(产生与上述相同的躲避图):

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


我不明白为什么堆叠的效果很好,而躲避的功能却不能将它们并排放置而不是放在顶部。



预计到达时间:我在ggplot google组上找到了关于此的recent question,并建议添加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

最佳答案

我认为问题在于您想堆叠在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)




如果您还添加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")

08-19 22:59