【问题标题】:Kernel Density Estimate (Probability Density Function) is wrong?Kernel Density Estimate(概率密度函数)错了?
【发布时间】:2021-03-09 09:46:27
【问题描述】:

我创建了一个直方图来显示连环杀手首次被杀的年龄密度,并尝试在其上叠加一个概率密度函数。但是,当我在 ggplot2 中使用 geom_density() 函数时,我得到的密度函数看起来太小了(面积

    #Histograms for Age of First Kill: 
library(ggplot2)
AFKH <- ggplot(df, aes(AgeFirstKill,fill = cut(AgeFirstKill, 100))) +
  geom_histogram(aes(y=..count../sum(..count..)), show.legend = FALSE, binwidth = 3) + # density wasn't working, so had to use the ..count/../sum(..count..)
  scale_fill_discrete(h = c(200, 10), c = 100, l = 60) + # c =, for color, and l = for brightness, the #h = c() changes the color gradient
  theme(axis.title=element_text(size=22,face="bold"), 
        plot.title = element_text(size=30, face = "bold"),
        axis.text.x = element_text(face="bold", size=14),
        axis.text.y = element_text(face="bold", size=14)) +
  labs(title = "Age of First kill",x = "Age of First Kill", y = "Density")+
  geom_density(aes(AgeFirstKill, y = ..density..), alpha = 0.7, fill = "white",lwd =1, stat = "density")
AFKH

【问题讨论】:

  • 第二个图中的直方图错误,而不是天性:列的高度太大了。密度似乎还可以,因为它与第一个图相同。
  • 可以给我们一个minimal reproducible example吗?如果您希望直方图和密度匹配,您可能应该使用..density..,它也考虑了 bin 宽度

标签: r ggplot2 statistics histogram kernel-density


【解决方案1】:

我们没有你的数据集,所以让我们制作一个相当接近它的数据集:

set.seed(3)
df <- data.frame(AgeFirstKill = rgamma(100, 3, 0.2) + 10)

首先要注意的是密度曲线不会改变。仔细查看绘图上的 y 轴。您会注意到密度曲线的峰值没有变化,但仍保持在 0.06 左右。变化的是直方图条的高度,y轴也随之变化。

这样做的原因是您没有将直方图条的高度除以它们的宽度来保留它们的面积。你的审美应该是..count../sum(..count..)/binwidth 以保持这个不变。

为了展示这一点,让我们将您的绘图代码包装在一个函数中,该函数允许您指定 bin 宽度,但在绘图时也将 binwidth 考虑在内:

draw_it <- function(bw) {
  ggplot(df, aes(AgeFirstKill,fill = cut(AgeFirstKill, 100))) +
  geom_histogram(aes(y=..count../sum(..count..)/bw), show.legend = FALSE, 
                 binwidth = bw) +
  scale_fill_discrete(h = c(200, 10), c = 100, l = 60) + 
  theme(axis.title=element_text(size=22,face="bold"), 
        plot.title = element_text(size=30, face = "bold"),
        axis.text.x = element_text(face="bold", size=14),
        axis.text.y = element_text(face="bold", size=14)) +
  labs(title = "Age of First kill",x = "Age of First Kill", y = "Density") +
  geom_density(aes(AgeFirstKill, y = ..density..), alpha = 0.7, 
               fill = "white",lwd =1, stat = "density")
}

现在我们可以这样做了:

draw_it(bw = 1)

draw_it(bw = 3)

draw_it(bw = 7)

【讨论】:

  • 我认为..density.. 可能等同于..count../sum(..count..)/binwidth ...
  • @BenBolker 我认为这是对的,但 OP 说 ..density.. 对他们不起作用
  • 也可以使用较新的after_stat(ndensity) 代替..density..
  • @Phil 我认为问题出在 OP 使用的填充比例上。 ..density..stat(density)after_stat(density) 都不会保留此处的配色方案。这很容易用我的代码进行测试。如果您能想出一种使用after_stat(density) 并保留填充颜色的方法,那就太好了。
  • 我认为填充颜色是个坏主意:-)
猜你喜欢
  • 2012-11-21
  • 2016-06-07
  • 2017-09-20
  • 2019-07-19
  • 2015-07-31
  • 2019-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多