【问题标题】:"Density" curve overlay on histogram where vertical axis is frequency (aka count) or relative frequency?“密度”曲线叠加在直方图上,其中垂直轴是频率(又名计数)或相对频率?
【发布时间】:2015-02-21 01:39:02
【问题描述】:

当垂直轴是频率或相对频率时,有没有一种方法可以覆盖类似于密度曲线的东西? (不是实际的密度函数,因为面积不需要积分为 1。)以下问题类似: ggplot2: histogram with normal curve,用户自行回答在 geom_density() 内扩展 ..count.. 的想法。然而,这似乎不寻常。

以下代码会产生一个过度膨胀的“密度”线。

df1            <- data.frame(v = rnorm(164, mean = 9, sd = 1.5))
b1             <- seq(4.5, 12, by = 0.1)
hist.1a        <- ggplot(df1, aes(v)) + 
                    stat_bin(aes(y = ..count..), color = "black", fill = "blue",
                             breaks = b1) + 
                    geom_density(aes(y = ..count..))
hist.1a

【问题讨论】:

    标签: r ggplot2


    【解决方案1】:

    @joran 的回复/评论让我开始思考合适的比例因子是多少。为了后代的缘故,这是结果。

    当垂直轴是频率(又名计数)时

    因此,在 bin 计数中测量的垂直轴的比例因子是

    在这种情况下,N = 164 和 bin 宽度为 0.1,平滑线中 y 的美感应该是:

    y = ..density..*(164 * 0.1)
    

    因此,以下代码会生成一条“密度”线,该线针对以频率(也称为计数)测量的直方图进行缩放。

    df1            <- data.frame(v = rnorm(164, mean = 9, sd = 1.5))
    b1             <- seq(4.5, 12, by = 0.1)
    hist.1a        <- ggplot(df1, aes(x = v)) + 
                        geom_histogram(aes(y = ..count..), breaks = b1, 
                                       fill = "blue", color = "black") + 
                        geom_density(aes(y = ..density..*(164*0.1)))
    hist.1a
    

    当纵轴为相对频率时

    使用上面的,我们可以写

    hist.1b        <- ggplot(df1, aes(x = v)) + 
                        geom_histogram(aes(y = ..count../164), breaks = b1, 
                                       fill = "blue", color = "black") + 
                        geom_density(aes(y = ..density..*(0.1)))
    hist.1b
    

    当纵轴为密度时

    hist.1c        <- ggplot(df1, aes(x = v)) + 
                        geom_histogram(aes(y = ..density..), breaks = b1, 
                                       fill = "blue", color = "black") + 
                        geom_density(aes(y = ..density..))
    hist.1c
    

    【讨论】:

    • 是否可以提取出这个..density..的值?
    • @amrrs,请参阅此处了解如何提取直方图值。类似的黑客会给你带来密度(但可能有更简单的方法)。 stackoverflow.com/questions/7740503/…
    • @Pat W。这是一个很好的答案。一个非常小的评论:要获得边缘没有垂直位和水平线轮廓的密度曲线,这是一种方法:geom_line(aes(y = ..density..), stat = "density", lwd=1),如果需要,可以调整 lwd 以加粗线。
    【解决方案2】:

    试试这个:

    ggplot(df1,aes(x = v)) + 
       geom_histogram(aes(y = ..ncount..)) + 
       geom_density(aes(y = ..scaled..))
    

    【讨论】:

    • 如果我们不想将计数缩放到 1,您知道该怎么做吗?
    • @PatW。平滑的密度估计和分箱计数不在同一尺度上(正如您在第一次尝试中观察到的那样)。要对齐它们,您必须将它们放在相同的比例上。您可以根据自己的喜好调整该比例,但需要进行一些调整。
    【解决方案3】:
    library(ggplot2)
    smoothedHistogram <- function(dat, y, bins=30, xlabel = y, ...){
      gg <- ggplot(dat, aes_string(y)) + 
        geom_histogram(bins=bins, center = 0.5, stat="bin", 
                       fill = I("midnightblue"), color = "#E07102", alpha=0.8) 
      gg_build <- ggplot_build(gg)
      area <- sum(with(gg_build[["data"]][[1]], y*(xmax - xmin)))
      gg <- gg + 
        stat_density(aes(y=..density..*area), 
                     color="#BCBD22", size=2, geom="line", ...)
      gg$layers <- gg$layers[2:1]
      gg + xlab(xlabel) +  
        theme_bw() + theme(axis.title = element_text(size = 16),
                           axis.text = element_text(size = 12))
    }
    

    dat <- data.frame(x = rnorm(10000))
    smoothedHistogram(dat, "x")
    

    【讨论】:

      猜你喜欢
      • 2015-10-11
      • 2020-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多