整合直方图和密度曲线,一个轴表示频率,另一个轴表示密度。

3

我正在使用hist()lines()函数创建带有密度叠加的直方图,并希望有一个显示频率而不是密度的y轴

是否有任何方法可以使用hist()而不使用ggplot来实现这一点?最好将频率轴作为右侧的第二个y轴。这是我的代码:

g <- rnorm(2000,5,1)
h<-hist(g, breaks=50, col="bisque",     
        border="black",ylab="Frequeny",yaxt='n',
        main="Title",xlab=paste0("Cr","(mg/dL)"),prob=TRUE) 
Axis(side=2, at=seq(0, 200, by=20))
lines(density(g),col="dimgray") #For Overlay

设置 prob = FALSE 是无效的,因为这会导致密度叠加图不起作用。

1个回答

6

首先生成数据和 hist 对象:

set.seed(0)  ## added for reproducibility
g <- rnorm(2000, 5, 1)
h <- hist(g, breaks = 50, plot = FALSE)

我通过plot = FALSE暂时抑制了绘图。

问题是,我们希望有两个y轴:

  • 左边的轴显示计数/频率;
  • 右边的轴显示密度。

基本上,我们在两个轴上都添加密度值的刻度标记,但是

  • 在左侧轴上显示相应的计数/频率;
  • 在右侧轴上显示密度值。

hist对象中的密度值为h$density。为了得到漂亮的图形,我们应用pretty()来获取刻度标记位置:

pos <- pretty(h$density, n = 5)
# [1] 0.0 0.1 0.2 0.3 0.4 0.5 0.6

为了找到在pos处相应的计数,我们需要执行以下操作:
freq <- round(pos * length(g) * with(h, breaks[2] - breaks[1]))
# [1]   0  20  40  60  80 100 120

这里使用的 round() 函数只是为了确保有限精度计算产生的小数被舍弃,以便获得整数。
现在我们可以开始制作集成直方图了。记得将右边距加大,以留出足够的空间给右轴的标识。以下代码中,我们将右边距设为与左边距相同。
new.mai <- old.mai <- par("mai")
new.mai[4] <- old.mai[2]
par(mai = new.mai)

graphics:::plot.histogram(h, freq = FALSE, col="bisque", main="Integrated Histogram",
                          xlab = paste0("Cr","(mg/dL)"), ylab="Frequeny",
                          border="black", yaxt='n')
Axis(side = 2, at = pos, labels = freq)
Axis(side = 4, at = pos, labels = pos)
mtext("Density", side = 4, line = 3)
lines(density(g), col="dimgray")

par(mai = old.mai)

注意我使用了graphics:::plot.histogram来绘制一个hist对象的直方图,并使用mtext在边缘添加文本。阅读?plot.histogram?mtext获取更多信息。 enter image description here

谢谢李哲远!这个完美地运行了,我不必停止使用hist()。 - L. C. M.
李哲源,是的,这非常酷!我希望我能够为你的回答点赞! - L. C. M.

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