首页 文章

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

提问于
浏览
14

我有很多时间理解 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")

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

它看起来很棒,但请注意新的最大值 . 看起来它只是从y11值的 test 中获取每个名称因子级别的最大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")

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


ETA: 我在ggplot google组中找到了一个recent question,并建议添加 alpha=0.5 以查看ggplot从每个分组获取最大值的's going on. It isn';它实际上是为每个值过度绘制了彼此重叠的条形图 .

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

似乎 stat="identity" 应该告诉ggplot计算在 aes() 内传递的 y=val 而不是在没有 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 回答

  • 17

    我认为问题是你想要在 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")
    

    Stacked bars

    如果你躲闪,你会得到在 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)
    

    Dodged on num

    如果你还将 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)
    

    Dodge all bars

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

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

    Summarized beforehand

相关问题