在R ggplot中将直方图y轴归一化为按组比例

44

我的问题非常类似于在 R ggplot 中将直方图的 y 轴归一化为比例,不同的是我有两组大小不同的数据,并且我希望每个比例相对于其组大小而不是总大小。

为了更清楚地说明,假设我在一个数据框中有两组数据:

dataA<-rnorm(100,3,sd=2)
dataB<-rnorm(400,5,sd=3)
all<-data.frame(dataset=c(rep('A',length(dataA)),rep('B',length(dataB))),value=c(dataA,dataB))

我可以用以下代码同时绘制这两个分布:

ggplot(all,aes(x=value,fill=dataset))+geom_histogram(alpha=0.5,position='identity',binwidth=0.5)

而不是在Y轴上显示频率,我可以使用比例:

ggplot(all,aes(x=value,fill=dataset))+geom_histogram(aes(y=..count../sum(..count..)),alpha=0.5,position='identity',binwidth=0.5)

但是这只是相对于总数据大小(这里有500个数据点)的比例:是否可以将其相对于每个组的大小呢?

我的目标是使得在A和B之间的一个给定区间内的数值比例可以在视觉上进行比较,而不受它们各自大小的影响。欢迎提出与我的原始想法不同的想法!

谢谢!

1个回答

59

像这样吗?[根据原帖评论进行了编辑]

ggplot(all,aes(x=value,fill=dataset))+
  geom_histogram(aes(y=0.5*..density..),
                 alpha=0.5,position='identity',binwidth=0.5)

使用y = ..density..会对直方图进行缩放,使得每个直方图下的面积为1,即sum(binwidth*y)=1.因此,您需要使用y=binwidth*..density..来表示每个区间中总数的分数。在您的情况下,binwidth=0.5.

我认为这样更容易解释:

ggplot(all,aes(x=value,fill=dataset))+
  geom_histogram(aes(y=0.5*..density..),binwidth=0.5)+
  facet_wrap(~dataset,nrow=2)

2
谢谢您的回答,但实际上我不认为密度等同于将计数除以数据集,除非条形宽度为1(请参见https://dev59.com/4mgt5IYBdhLWcg3w2RCU)。特别是在我的情况下,我想读取Y轴上一个bin所代表的百分比。 - Erwan
你是对的 - 需要按照binwidth进行缩放。请看我的修改。 - jlhoward
4
是的,当我回复时我甚至没有意识到这一点,我想我过于专注于带有y=..count../sum(..count..)版本了。显然,使用..count../sum(..count..)会将每个计数除以总计数,而在..density..的情况下,它则应用于每个组别独立地:我仍然不明白为什么,如果你有任何想法,请告诉我。 - Erwan
3
我刚遇到了这个问题。根据 https://github.com/tidyverse/ggplot2/issues/3522,你可以尝试使用`aes(y = stat(density*width))`,这将达到相同的结果,但无需手动设置 binwidth。然而,目前仍然不太清楚这是否是被允许的。 - Marius

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接