【问题标题】:Binned Histogram with overlay of empirical and/or normal distribution [duplicate]叠加经验和/或正态分布的分级直方图 [重复]
【发布时间】:2022-01-18 00:32:12
【问题描述】:

我正在尝试查看某个变量的频率分布。由于数据量很大,我为一系列值创建了 bin,并绘制了每个 bin 的计数。我希望能够覆盖线,这些线既代表了我的数据看到的经验分布,也代表了理论上的正态分布。我可以通过执行以下操作来完成此操作,而无需预先分箱我的数据或使用 ggplot2:

df <- ggplot2::diamonds
hist(df$price,freq = FALSE)
lines(density(df$price),lwd=3,col="blue")

或者像这样使用ggplot2:

mean_price <- mean(df$price)
sd_price <- sd(df$price)

ggplot(df, aes(x = price)) +
  geom_histogram(aes(y = ..density..), 
                 bins = 40,  colour = "black", fill = "white") +
  geom_line(aes(y = ..density.., color = 'Empirical'), stat = 'density') +     
  stat_function(fun = dnorm, aes(color = 'Normal'),
                args = list(mean = mean_price, sd = sd_price)) +
  scale_colour_manual(name = "Colors", values = c("red", "blue"))

但我不知道如何在我的预分箱数据上叠加类似的线条:

breaks <- seq(from=min(df$price),to=max(df$price),length.out=11)
price_freq <- cut(df$price,breaks = breaks,right = TRUE,include.lowest = TRUE)
ggplot(data = df,mapping = aes(x=price_freq)) +
  stat_count() +
  theme(axis.text.x = element_text(angle = 270)) 
  # + geom_line(aes(y = ..density.., color = 'Empirical'), stat = 'density') +     
  # stat_function(fun = dnorm, aes(color = 'Normal'),
  #               args = list(mean = mean_price, sd = sd_price)) +
  # scale_colour_manual(name = "Colors", values = c("red", "blue"))

有什么想法吗?

【问题讨论】:

  • 另外,这个线程链接到许多其他处理相同问题的线程

标签: r ggplot2 frequency-distribution


【解决方案1】:

您的问题是 cut 为您的 x 轴提供了一个因子/字符。您需要一个数字 x 轴来添加其他图层。第一步可能是尝试以下方法。我加了一个小软糖来解决最后一个垃圾箱。

library(tidyverse)
df <- ggplot2::diamonds

mean_price <- mean(df$price)
sd_price <- sd(df$price)

num_bins <- 40
breaks <- seq(from=min(df$price),to=max(df$price)+1e-10,length.out=num_bins+1)
midpoints <- (breaks[1:num_bins] + breaks[2:(num_bins+1)])/2

precomputed <- df %>% 
    mutate(bin_left = breaks[findInterval(price, breaks)],
           bin_mid = midpoints[findInterval(price, breaks)]) %>%
    count(bin_mid) 

precomputed %>% 
    ggplot(aes(x = bin_mid, weight = n)) +
    geom_histogram(aes(y = ..density..), bins = num_bins, boundary = breaks[1], colour = "black", fill = "white") +
    geom_line(aes(y = ..density.., color = 'Empirical'), stat = 'density') +
    stat_function(fun = dnorm, aes(color = 'Normal'),
                  args = list(mean = mean_price, sd = sd_price)) +
    scale_colour_manual(name = "Colors", values = c("red", "blue"))

但是您会注意到红色的经验曲线与您的 ggplot2 示例完全不同。原因是这里是使用将所有 x 值移动到 bin 中点的汇总数据来计算的。您将需要预先计算此经验曲线,或将其丢弃并依靠直方图来表示此数据。

对不起,部分答案。

【讨论】:

    【解决方案2】:

    看看 PearsonDS 包(我猜你没有使用 rnorm 是有原因的)。最简单的方法可能是生成满足您要求的数据向量并使用 geom_line 映射该向量。

    library("PearsonDS")
    df <- rpearson(5000,moments=c(mean=10,variance=2,skewness=0,kurtosis=3))
    

    【讨论】:

      最近更新 更多