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

Hen*_*ndy 17 plot r ggplot2

我有很多时间理解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))
Run Code Online (Sandbox Code Playgroud)

我使用该示例,因为它类似于支出与预算示例.支出每个names因素级别有很多行,而预算只有一个(每个类别一个预算金额).

对于堆积条形图,这非常有用:

ggplot(df, aes(x=factor(names), y=values, fill=factor(num))) +
geom_bar(stat="identity")
Run Code Online (Sandbox Code Playgroud)

堆积的情节

特别要注意y值maxes.他们是数据从资金test与价值观test2上的蓝色的顶部.

根据我读过的其他问题,我只需要添加position="dodge"一个并排的情节而不是叠加的情节:

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

回避

它看起来很棒,但请注意新的最大值.看起来它只是从y值中取每个名称因子级别的最大testy值.它不再是他们的总结.

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

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

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


ETA:我在ggplot google小组上发现了一个关于此问题最新问题,建议添加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
Run Code Online (Sandbox Code Playgroud)

正确

wch*_*wch 20

我认为问题在于你想要在组堆叠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)
)
Run Code Online (Sandbox Code Playgroud)

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

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

堆积的酒吧

如果你躲闪,你会得到在值之间躲过的柱子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)
Run Code Online (Sandbox Code Playgroud)

躲在数字上

如果您还添加id为分组var,它将躲避所有这些:

# 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)
Run Code Online (Sandbox Code Playgroud)

避开所有酒吧

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

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")
Run Code Online (Sandbox Code Playgroud)

事先总结一下

  • `geom_bar`可能有点混乱,因为它用于两个不同的目的:有时它用于绘制你提供的y值,有时它会计算每个中的个案数量并将该计数用作y值(使用`stat = "BIN"`).后一种行为是默认的(您可以使用`ggplot(df,aes(x = factor(names),fill = factor(num)))+ geom_bar(color ="black")`)来查看它.在这种情况下,"堆叠"并不完全相同 - 它是摘要_stat_,而通常的堆叠是_position adjustment_.这些事情发生在ggplot管道的不同阶段. (2认同)