【问题标题】:Drawing a theoretical density histogram in R?在 R 中绘制理论密度直方图?
【发布时间】:2017-11-26 05:20:37
【问题描述】:

我想知道是否有可能为 R 中的给定连续分布绘制 理论 密度直方图?

理论直方图是指不基于 R 中可用的随机变量生成器的直方图(例如,hist(rnorm(1e4)))。相反,一个直方图完全匹配所讨论的连续分布的概率密度函数 (pdf),用于用户定义的支持(即,随机变量的范围)具有可调整的中断。

作为 R 中的示例,我们知道支持 -5 到 5 的标准正态分布的 pdf 在理论上 的形状类似于 R下面的代码。

在 R 中,我们可以将 这个精确的理论 pdf 转换为相应的理论密度直方图吗?关于如何在 R 中做到这一点的任何建议?

c = curve(dnorm(x), -5, 5, n = 1e4)

【问题讨论】:

  • 没有办法将连续分布与直方图“完全匹配”。任何直方图都是不可挽回的离散。
  • theoretical pdf (probability density function)和theoretical density histogram有什么区别?
  • 如果你已经有了 pdf,我会使用 predict 和你的休息时间,然后是一个条形图
  • 定义你想要的“多近”。什么级别的错误是可以接受的?正态分布的域为 [-Inf, +Inf]
  • 这是...的副本...将密度曲线拟合到 R 中的直方图:stackoverflow.com/questions/1497539/…

标签: r plot histogram distribution


【解决方案1】:

对于任意函数,使用积分函数:

c = curve(dnorm, -5, 5, n = 1e4)
breaks <- pretty(c[[1]], nclass.Sturges(c[[1]]))

bar_x <- sapply(1:(length(breaks)-1), function(i) {
    (breaks[i]+breaks[i+1])/2
})

bar_y <- sapply(1:(length(breaks)-1), function(i) {
    integrate(dnorm, breaks[i], breaks[i+1])$value
})

barplot(bar_y, names.arg=bar_x)

【讨论】:

  • 请运行以下命令:barplot(bar_y, names.arg=bar_x, ylim = c(0, max(c$y)) )。这很好用,但我确信max(c$y) 接近.4 而y 轴上的最大数字是.3?实际上,这种情况下barplot 的最大中间条的高度应该与.4 一样高,但不是。有什么办法解决吗?
  • 条高的值由积分值决定。所以 bar 的值大致是 y * dx。如果您希望该值与曲线相同,则只需除以 dx,这将是该区间内的平均 y 值。例如。 integrate(dnorm, breaks[i], breaks[i+1])$value / (breaks[i+1] - breaks[i])
  • 所以,有两件事。首先,y 轴的最大值不会成为曲线的最大值。其次,我们无法将曲线拟合到条形图上,即curve(dnorm(x), -5, 5, n = 1e4, add = T) 仍然需要移动。
  • 只是为了给出更大的图景,假设我获得了称为后验的密度函数的值:prior = function(x) dnorm(x) ; likelihood = function(x) dt(1.46, 19, x*sqrt(20)) ; marginal = integrate(function(x) prior(x)*likelihood(x), -Inf, Inf)[[1]] ; posterior = function(x) prior(x)*likelihood(x) / marginal
  • 我通常可以这样绘制posterior:plot(x &lt;- seq(-5, 5, len = 1e3), posterior(x), col = 3, t = "l"),但真的需要将此图显示为直方图吗?
【解决方案2】:

你可以用理论上的累积密度来做这件事。通过取区域任一端的累积分布值之间的差异,您可以得到应该为每个区域分配多少概率。这些应该由区域的宽度加权。下面的示例使用正态分布。

barplot(diff(2*pnorm(c(-Inf, seq(-4,4,0.5), Inf))), ylim=c(0,0.4))

当然,如果你只有密度,没有累积密度,你可能要积分。

请注意,条形图上的 x 轴是 bin 的索引号,而不是实际的 x 值。因此,如果您只是在此之上绘制范数密度函数,它将不会对齐。但是,很容易在坐标中进行线性移动,这将导致 pdf 正确排列。对于此示例,分布的中心位于 10.9,每个宽度为 0.5 的 bin 在新比例中占据 1.2,因此您使用 (x-10.9)/2.4 转换 x。要覆盖曲线,请尝试

barplot(diff(2*pnorm(c(-Inf, seq(-4,4,0.5), Inf))), ylim=c(0,0.4))
Shifted = function(x) dnorm((x-10.9)/2.4)
curve(Shifted, 0.5,21.5, add = T) 

抱歉,从这台机器上传图片时遇到问题。

【讨论】:

  • 这比我用 dnorm 和 seq() 组合起来的答案更快更干净
  • @G5W - 为什么不barplot((dnorm(c(-Inf, seq(-4,4,0.5), Inf))), ylim=c(0,0.4))?
  • 那是因为 x 值不匹配。我图上的 x 值是 bin 的索引号,而不是实际的 x 值。您可以移动 pdf 以使其适合,但我需要一些时间来计算翻译因子。
  • 好的,谢谢。我注意到两个图之间的条形偏移了 1/2
  • @DanSlone 没有 2 = 1/(0.5) 您将获得该地区的面积。但是我们想要该区域中 pdf 的平均高度,所以我们必须除以 bin 的宽度。我的箱子的宽度是 0.5,所以你需要乘以 1/0.5 = 2
猜你喜欢
  • 1970-01-01
  • 2017-06-08
  • 2014-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-04
  • 1970-01-01
相关资源
最近更新 更多