【问题标题】:Plot normal distribution onto data在数据上绘制正态分布
【发布时间】:2017-09-07 07:24:38
【问题描述】:

我有一些想要转换的对数正态数据,然后拟合正态分布。这是一个可重现的示例,其中的数据不完全是对数正态的,但已经足够接近了:

# create some lognormal data
dat <- data.frame(x = c(runif(1000, 0, 1), runif(300, 1, 100), runif(100,100,1000)))

我可以用log10 转换这些数据,并用MASS::fitdistr 拟合它们的正态分布。

# fit normal distribution to log-transformed values
library(MASS)
fit <- fitdistr(log10(dat$x), densfun = "normal")
fit$estimate # mean and SD of the normal distribution

现在我想绘制数据,以及它上面的分布。我通过 log10 转换我的数据,并用stat_function 绘制正态分布,但它不适合数据。

# plot data and distribution
ggplot(data = dat) +
  geom_histogram(mapping = aes(x = log10(x))) +
  stat_function(fun = dnorm, args = list(mean = fit$estimate[1], sd = fit$estimate[2], log = TRUE))

任何指示以及验证我是否正确进行此操作都会非常有帮助。

最后要让我的 x 轴显示 10、100、1000 等单位...我应该使用 scale_x_log10() 吗?格式化x轴的简单方法是什么?

【问题讨论】:

  • 对数(均匀分布)不是对数正态

标签: r ggplot2 normal-distribution


【解决方案1】:

当您想在同一张图上绘制直方图和密度分布时,您需要使用美学 y=..density..
绘制 密度直方图 这是一个例子。为了清楚起见,我从对数正态分布中生成数据。

set.seed(123)
# Generate data from a log-normal distribution
dat <- data.frame(x=rlnorm(10000))

# Fit normal distribution to log-transformed values
library(MASS)
fit <- fitdistr(log10(dat$x), densfun = "normal")

# Plot density histogram and fitted distribution
ggplot(data = dat) +
  geom_histogram(mapping = aes(x = log10(x), y = ..density..), col="white") +
  stat_function(fun = dnorm, 
      args = list(mean = fit$estimate[1], sd = fit$estimate[2], log = F), 
      color="red", lwd=1)

【讨论】:

  • 这正是我想要的。谢谢@Marco!还有一个(也许是快速的)问题,在这个例子中,你推荐什么来格式化 x 轴?你会使用 scale_x_log10()simply scale_x_continuous() 在 1、10、100、1000...
  • @RichPauloo 在我看来,上图的 x 轴是可以的。解释很清楚:在 x 轴上有 x 的对数值,因此 1 表示 10,2 表示 100,依此类推...
  • @RichPauloo 否则,您可以使用scale_x_continuous。我认为你不应该使用scale_x_log10()
  • 感谢@Marco 的提示,以及超级清晰的示例。 :)
  • @RichPauloo 您完成了大部分代码!您只是忘记使用密度而不是计数..!