【问题标题】:Changing binwidth of density histogram so that probabilities sum up to 1更改密度直方图的 binwidth 以使概率总和为 1
【发布时间】:2017-12-05 12:18:51
【问题描述】:

我已经发现了很多问题,但不知何故它并没有真正帮助我。我不明白如何更改 ggplot2 中密度直方图中的 binwidth,以便概率总和为 1。似乎只有在 binwidth 正好为 1 时才有效。 这是一个例子:

set.seed(1)
df = data.frame("data" = runif(1000, min=0, max=100))

a = ggplot(data = df, aes(x = data))+  
    geom_histogram(aes(y=..density..),colour="black", fill = "white", 
    breaks=seq(0, 100, by = 50)) 


b = ggplot(data = df, aes(x = data))+  
    geom_histogram(aes(y =..density..), 
             breaks=seq(0, 100, by = 30), 
             col="black", 
             fill="white") 
c = ggplot(data = df, aes(x = data))+  
    geom_histogram(aes(y =..density..), 
             breaks=seq(0, 100, by = 10), 
             col="black", 
             fill="white")

d = ggplot(data = df, aes(x = data))+  
    geom_histogram(aes(y =..density..), 
             breaks=seq(0, 100, by = 1), 
             col="black", 
             fill="white") 

grid.arrange(a,b,c,d, ncol= 2)

如果你看概率轴,你可以看到前三个图肯定是错误的。这些不是正确的直方图,因为 bin 总和不等于 1。y 轴甚至不会根据直方图 a、b、c 或 d 发生显着变化。我还尝试用“binwidth”命令替换“breaks”命令,但情况更糟。 我还想知道如何计算直方图的单个 bin 的概率来证明它的总和是否为 1?

感谢您的帮助。

【问题讨论】:

  • 您应该检查 y 轴上的密度值代表什么。这不是概率。在许多情况下,这些值可以是 1。请尝试改用 aes(y=..count../sum(..count..))
  • 这里有一些有用的信息:stats.stackexchange.com/questions/4220/…

标签: r ggplot2 histogram


【解决方案1】:

模拟一些数据:

library(ggplot2)
library(dplyr)

set.seed(1)
df = data.frame("data" = runif(1000, min=0, max=100))

你可以得到的第一个情节是:

# y axis has the density estimate values 
ggplot(data = df, aes(x = data))+  
  geom_histogram(aes(y=..density..),colour="black", fill = "white", 
                 breaks=seq(0, 100, by = 50))

此图在 y 轴上具有密度估计值。这些值对应于密度图,而不是您创建的条形图。你可以看到这个版本的密度图被覆盖了:

# y axis has the density estimate values and the density plot
ggplot(data = df, aes(x = data))+  
  geom_histogram(aes(y=..density..),colour="black", fill = "white", 
                 breaks=seq(0, 100, by = 50)) +
  geom_density(aes(data), col="red")

解释这一点的一种方法是,红线上的每个点都有一个被选中的概率,并且位于 y 轴上(即,很多点意味着概率趋向于零)。

你可以用这个得到你想要的:

# y axis has the probabilities of each bar (bar counts / all counts)
ggplot(data = df, aes(x = data))+  
  geom_histogram(aes(y=..count../sum(..count..)),colour="black", fill = "white", 
                 breaks=seq(0, 100, by = 50)) 

在保持数据(以备将来使用或仅检查概率总和为 1)的同时执行上述操作的另一种方法是:

# assign the breaks
breaks = cut(df$data, seq(0, 100, by = 50))

# count observations in each bar and probability of each bar
df %>%
  mutate(Breaks = breaks) %>%
  count(Breaks) %>%
  mutate(Prc = n/sum(n))

# # A tibble: 2 x 3
#     Breaks     n   Prc
#     <fctr> <int> <dbl>
# 1   (0,50]   520  0.52
# 2 (50,100]   480  0.48

# plot the above
df %>%
  mutate(Breaks = breaks) %>%
  count(Breaks) %>%
  mutate(Prc = n/sum(n)) %>%
  ggplot(aes(Breaks, Prc)) + geom_col()

【讨论】:

  • 这是一个非常好的答案。现在我也更详细地了解了那里发生的事情。非常感谢!!
  • 并使用命令 sum(df$Prc) 可以看到它的总和为 1,您甚至可以选择单个元素来查看它的概率。太好了。
  • 选择单个元素:df[df$Breaks=="(0,50]",3]
  • 假设df 是具有百分比的数据集,您可以使用df$Prc[df$Breaks=="(0,50]"] 来避免使用列位置,而是使用列名。更容易解释(给我来自df 的百分比,其中 Breaks 是 (0,50])。
猜你喜欢
  • 2011-04-21
  • 2013-02-02
  • 2017-07-17
  • 2014-04-10
  • 1970-01-01
  • 1970-01-01
  • 2015-12-01
  • 2011-08-25
相关资源
最近更新 更多