我有足够的时间来理解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 one和this 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")