在R中将两个直方图标准化后绘制在一起

16

我意识到有很多人询问如何在R中将两个直方图侧边并排绘制(即在一个图中将条形图相邻地放置)以及如何对数据进行归一化。根据我找到的建议,我能够完成其中一个操作,但不能同时完成两种操作。

这是设置。 我有两个长度不同的数据框,想要将每个数据框中对象的体积作为直方图绘制出来。例如,在数据框1中有多少个对象的体积在0.1-0.2 um^3之间,并将其与数据框2中在0.1-0.2 um^3之间的对象数量进行比较。覆盖或并排放置都可以实现此目的。

由于一个数据框中的测量数量比另一个数据框多,因此我必须进行归一化处理,所以我使用:

read.csv(ctl)
read.csv(exp)
h1=hist(ctl$Volume....)
h2=hist(exp$Volume....

#to normalize#

h1$density=h1$counts/sum(h1$counts)*100
plot(h1,freq=FALSE....)
h2$density=h2$counts/sum(h2$counts)*100
plot(h2,freq=FALSE....)

现在我已经成功地使用这种方法叠加了未经归一化的数据:http://www.r-bloggers.com/overlapping-histogram-in-r/,以及使用这种方法:plotting two histograms together

但是,当涉及到如何叠加归一化数据时,我遇到了困难。


1
“Side by side” 是什么意思?是指两个不同的图表并排放置(par(mfrow=c(1,2))),还是指一个图表中有两个不同的柱状图并排放置? - James
一个图表有两个不同的条形,抱歉之前表述不够清晰。 - Harry B
我不知道$Volume是什么,我猜它是你想要归一化的向量。这很笨拙,但在数据框中创建一个新向量,其中ctl$density <- ctl$Volume / max(ctl$Volume)。现在从中制作一个直方图h1 <- hist(ctl$density)。对于另一个数据集执行相同的操作,并按照你发布的网站上的说明进行操作。 - James
1个回答

22

ggplot2相对简单地绘制了不同大小组的归一化直方图。以下是使用虚假数据的示例:

ggplot2使得绘制不同大小组的归一化直方图相对简单。下面是使用虚假数据的示例:

library(ggplot2)

# Fake data (two normal distributions)
set.seed(20)
dat1 = data.frame(x=rnorm(1000, 100, 10), group="A")
dat2 = data.frame(x=rnorm(2000, 120, 20), group="B")
dat = rbind(dat1, dat2)

ggplot(dat, aes(x, fill=group, colour=group)) +
  geom_histogram(breaks=seq(0,200,5), alpha=0.6, 
                 position="identity", lwd=0.2) +
  ggtitle("Unormalized")

ggplot(dat, aes(x, fill=group, colour=group)) +
  geom_histogram(aes(y=..density..), breaks=seq(0,200,5), alpha=0.6, 
                 position="identity", lwd=0.2) +
  ggtitle("Normalized")

如果你想制作叠加密度图,也可以这样做。adjust控制带宽。默认情况下已经进行了归一化。

ggplot(dat, aes(x, fill=group, colour=group)) +
  geom_density(alpha=0.4, lwd=0.8, adjust=0.5) 

更新:针对您的评论,以下代码可以实现。 (..density..)/sum(..density..) 的结果是两个直方图的总密度相加为1,并且每个单独组的总密度相加为0.5。因此,您需要乘以2才能使每个组的总密度分别归一化为1。一般来说,您需要乘以n,其中n是组数。这似乎有点笨拙,可能会有更优雅的方法。

library(scales) # For percent_format()

ggplot(dat, aes(x, fill=group, colour=group)) +
  geom_histogram(aes(y=2*(..density..)/sum(..density..)), breaks=seq(0,200,5), alpha=0.6, 
                 position="identity", lwd=0.2) +
  scale_y_continuous(labels=percent_format())

enter image description here


非常感谢,工作得非常出色。我唯一的额外问题是是否可能让规格化的 ggplot 的 y 轴表示百分比而不是概率密度? - Harry B

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