【问题标题】:How to fit a curve to a histogram如何将曲线拟合到直方图
【发布时间】:2016-12-22 20:23:08
【问题描述】:

我已经探索过有关此主题的类似问题,但在我的直方图上生成漂亮的曲线时遇到了一些问题。我知道有些人可能会认为这是重复的,但我目前没有找到任何可以帮助解决我的问题的东西。

虽然数据在此处不可见,但我使用了一些变量,以便您可以在下面的代码中看到它们所代表的内容。

Differences <- subset(Score_Differences, select = Difference, drop = T)
m = mean(Differences)
std = sqrt(var(Differences))

这是我生成的第一条曲线(代码似乎最常见且易于生成,但曲线本身并不适合)。

hist(Differences, density = 15, breaks = 15, probability = TRUE, xlab = "Score Differences", ylim = c(0,.1), main = "Normal Curve for Score Differences")
curve(dnorm(x,m,std),col = "Red", lwd = 2, add = TRUE)

我真的很喜欢这个,但不喜欢曲线进入负值区域。

hist(Differences, probability = TRUE)
lines(density(Differences), col = "Red", lwd = 2)
lines(density(Differences, adjust = 2), lwd = 2, col = "Blue")

这是与第一个相同的直方图,但有频率。还是不太好看。

h = hist(Differences, density = 15, breaks = 15, xlab = "Score Differences", main = "Normal Curve for Score Differences")
xfit = seq(min(Differences),max(Differences))
yfit = dnorm(xfit,m,std)
yfit = yfit*diff(h$mids[1:2])*length(Differences)
lines(xfit, yfit, col = "Red", lwd = 2)

又一次尝试,但没有运气。可能是因为我用的是qnorm,数据明显不正常。曲线再次向负方向移动。

sample_x = seq(qnorm(.001, m, std), qnorm(.999, m, std), length.out = l)
binwidth = 3
breaks = seq(floor(min(Differences)), ceiling(max(Differences)), binwidth)
hist(Differences, breaks)
lines(sample_x, l*dnorm(sample_x, m, std)*binwidth, col = "Red")

唯一在视觉上看起来不错的曲线是第 2 条,但曲线落入了负方向。

我的问题是“有没有一种“标准方法”可以在直方图上放置曲线?”这个数据肯定是不正常的。我在这里介绍的 3 个程序来自类似的帖子,但显然我遇到了一些麻烦。我觉得所有拟合曲线的方法都取决于您使用的数据。


更新解决方案

感谢李哲元等人!我将把它留给我自己参考,希望其他人也能参考。

hist(Differences, probability = TRUE)
lines(density(Differences, cut = 0), col = "Red", lwd = 2)
lines(density(Differences, adjust = 2, cut = 0), lwd = 2, col = "Blue")

【问题讨论】:

  • 在我不提前知道分布的场景(即所有经验场景)中,我使用核密度(有时没有直方图)。如果您的目标是查看数据与特定分布的匹配程度,则可以将内核密度与已知分布一起绘制。
  • @lmo 我喜欢这个主意。不过,我的内核似乎偏离了直方图的方向。这很麻烦,但哦,好吧..谢谢你们俩。
  • 这真是一个统计问题。有许多方法可以估算密度,但以原则性的方式进行此操作需要与统计学家坐下来讨论调查的科学背景。

标签: r histogram curve-fitting kernel-density density-plot


【解决方案1】:

好的,所以您只是在为density 超出“自然范围”这一事实而苦苦挣扎。好吧,只需设置cut = 0。您可能想阅读plot.density extends “xlim” beyond the range of my data. Why and how to fix it? 了解原因。在那个答案中,我使用了fromto。但现在我使用的是cut

## consider a mixture, that does not follow any parametric distribution family
## note, by construction, this is a strictly positive random variable
set.seed(0)
x <- rbeta(1000, 3, 5) + rexp(1000, 0.5)

## (kernel) density estimation offers a flexible nonparametric approach
d <- density(x, cut = 0)

## you can plot histogram and density on the density scale
hist(x, prob = TRUE, breaks = 50)
lines(d, col = 2)

注意,cut = 0,密度估计严格在range(x) 内完成。在此范围之外,密度为 0。

【讨论】:

  • 啊!我现在明白了。哇,好方便。在大多数情况下,我似乎做得很好。感谢您的澄清和耐心。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-03
  • 1970-01-01
  • 1970-01-01
  • 2010-12-02
  • 1970-01-01
相关资源
最近更新 更多