【问题标题】:ggplot faceted cumulative histogramggplot 多面累积直方图
【发布时间】:2018-07-29 22:23:33
【问题描述】:

我有以下数据

set.seed(123)
x = c(rnorm(100, 4, 1), rnorm(100, 6, 1))
gender = rep(c("Male", "Female"), each=100)
mydata = data.frame(x=x, gender=gender)

我想用 ggplot 绘制两个累积直方图(一个用于男性,另一个用于女性)。 我试过下面的代码

ggplot(data=mydata, aes(x=x, fill=gender)) + stat_bin(aes(y=cumsum(..count..)), geom="bar", breaks=1:10, colour=I("white")) + facet_grid(gender~.)

但我得到了这张图表

这显然是不正确的。

我怎样才能得到正确的,像这样:

谢谢!

【问题讨论】:

    标签: r ggplot2


    【解决方案1】:

    我会预先计算每个组每个 bin 的 cumsum 值,然后使用 geom_histogram 进行绘图。

    mydata %>%
        mutate(x = cut(x, breaks = 1:10, labels = F)) %>%      # Bin x
        count(gender, x) %>%                                   # Counts per bin per gender
        mutate(x = factor(x, levels = 1:10)) %>%               # x as factor
        complete(x, gender, fill = list(n = 0)) %>%            # Fill missing bins with 0
        group_by(gender) %>%                                   # Group by gender ...
        mutate(y = cumsum(n)) %>%                              # ... and calculate cumsum
        ggplot(aes(x, y, fill = gender)) +                     # The rest is (gg)plotting
        geom_histogram(stat = "identity", colour = "white") + 
        facet_grid(gender ~ .)
    

    【讨论】:

    • Maurits,感谢您如此迅速地回答,但您的条形不完全符合间隔。此外,如果可能的话,我正在寻找一种更简单的方法,避免显式计算累积频率。
    • “Maurits,感谢您这么快地回答,但是您的条形不完全符合间隔。” 你是什么意思?数字以条形为中心,直方图应如此。在您的情况下,数字在 条之间,这是不正确的。
    • 在这种情况下,x 变量是连续的,因此我绘制了一个直方图。在直方图中,条形的宽度必须是区间的宽度。例如,第一个柱的底部必须是从 1 到 2 的区间,并且不应以 2 为中心。无论如何,我不太担心这一点。对我来说更重要的是是否有更简单的方法来做到这一点。再次感谢!
    • “在直方图中,条形的宽度必须是区间的宽度” @AlfredoSánchez 你从哪里听说过?这是不正确的,并且与直方图的标准定义和解释完全不一致。反正。我给了你我的两分钱和一个简单的解决方案。在ggplot 中进行数据操作是不好的做法,我当然不会称其为更简单的解决方案,但这显然是您的选择。
    • 你从哪里听说过?在很多书中。看看这些:wikihow.com/Draw-a-Histogramyoutube.com/watch?v=rhCq0Xcvg_E 再次感谢您的回答。如果没有人给我一个更简单的方法,我会采用你的。
    【解决方案2】:

    一百万年后的答案....

    我一直在为同样的问题寻找解决方案,我来到了这里..

    最后我自己弄明白了,所以我会把它放在这里以防其他人需要它。

    根据要求:无需任何准备工作!

    ggplot(mydata) +
        geom_histogram(aes(x = x, y = ave(..count.., group, FUN = cumsum), 
                           fill = gender, group = gender),
                           colour = "gray70", breaks = 1:10) +
        facet_grid(rows = "gender")
    

    【讨论】:

      【解决方案3】:

      和@Edo 一样,我也正是为了这个而来到这里。 @Edo 的解决方案对我来说是关键。这很棒。但我在这里发布了一些增加信息密度并允许在不同情况下进行比较的补充内容。

      library(ggplot2)
      
      set.seed(123)
      x = c(rnorm(100, 4, 1), rnorm(50, 6, 1))
      gender = c(rep("Male", 100), rep("Female", 50))
      grade = rep(1:3, 50)
      mydata = data.frame(x=x, gender=gender, grade = grade)
      
      ggplot(mydata, aes(x, 
                         y = ave(after_stat(density), group, FUN = cumsum)*after_stat(width),
                         group = interaction(gender, grade),
                         color = gender)) +
          geom_line(stat = "bin") +
          scale_y_continuous(labels = scales::percent_format()) +
          facet_wrap(~grade)
      

      我重新调整y 以便累积图始终以 100% 结束。否则,如果组的大小不同(就像它们在原始示例数据中一样),则累积图具有不同的最终高度。这掩盖了它们的相对分布。

      其次,我使用geom_line(stat="bin") 而不是geom_histogram(),这样我可以在面板上放置多行。这样我可以很容易地比较它们。

      最后,因为我还想跨方面进行比较,所以我需要确保ggplot 组变量不仅仅使用color=gender。我们使用group = interaction(gender, grade) 手动设置它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-05
        • 2018-10-25
        • 2021-03-19
        • 2013-08-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多