在直方图上绘制垂直分位线

4
我目前使用R中的ggplot生成以下图表:

数据存储在一个单一的数据框中,有三列:PDF(上图中的y轴)、mids(x轴)和数据集名称。这是从直方图中创建的。
我想要做的是为每个数据集绘制一个颜色编码的垂线,代表95分位数,就像我手动画在下面的例子中一样:

我尝试使用+ geom_line(stat="vline", xintercept="mean"),但当然我要找的是分位数,而不是平均值,据我所知,ggplot不允许这样做。颜色没问题。
我还尝试过+ stat_quantile(quantiles = 0.95),但我不确定它究竟是什么。文档非常缺乏。颜色又没问题。
请注意,密度值非常低,最低可达1e-8。我不知道quantile()函数是否支持这种情况。
我了解到,计算直方图的分位数与计算数字列表的分位数并不完全相同。我不知道它是否有帮助,但是HistogramTools软件包包含一个ApproxQuantile()函数,用于直方图分位数。
下面包含了最小工作示例。正如您所看到的,我从每个直方图获取一个数据框,然后将这些数据框绑定在一起并绘制出来。
library(ggplot2)
v <- c(1:30, 2:50, 1:20, 1:5, 1:100, 1, 2, 1, 1:5, 0, 0, 0, 5, 1, 3, 7, 24, 77)
h <- hist(v, breaks=c(0:100))
df1 <- data.frame(h$mids,h$density,rep("dataset1", 100))
colnames(df1) <- c('Bin','Pdf','Dataset')
df2 <- data.frame(h$mids*2,h$density*2,rep("dataset2", 100))
colnames(df2) <- c('Bin','Pdf','Dataset')
df_tot <- rbind(df1, df2)

ggplot(data=df_tot[which(df_tot$Pdf>0),], aes(x=Bin, y=Pdf, group=Dataset, colour=Dataset)) +
geom_point(aes(color=Dataset), alpha = 0.7, size=1.5)
1个回答

3

预先计算这些值并将它们分别绘制似乎是最简单的选择。使用 dplyr 这样做需要很少的努力:

library(dplyr)
q.95 <- df_tot %>%
  group_by(Dataset) %>%
  summarise(Bin_q.95 = quantile(Bin, 0.95))

ggplot(data=df_tot[which(df_tot$Pdf>0),], 
       aes(x=Bin, y=Pdf, group=Dataset, colour=Dataset)) +
  geom_point(aes(color=Dataset), alpha = 0.7, size=1.5) + 
  geom_vline(data = q.95, aes(xintercept = Bin_q.95, colour = Dataset))

enter image description here


1
这个程序绘制了Bin tho的95分位数。例如,在上面的图中,红色数据集从0到100,因此95分位数是简单的95,无论密度如何。也就是说,quantile(c(0:100), 0.95)。蓝色数据集同理。不幸的是,在直方图之前,我无法访问整个数据数组,因为它太大而无法放入内存。这就是为什么我需要使用直方图的原因。对于文件的每个层,我创建一个直方图。然后,我使用HistogramTools::AddHistrograms将它们合并成一个单一的直方图。 - AF7
这只是一个演示。其背后的想法是您需要提前计算分位数并从单独的数据框中绘制它们。我不知道如何正确计算这些,因为您的数据似乎相当复杂。如果您的问题本质上是关于如何计算分组数据的分位数(而不是如何使用geom_vline),请告诉我,我会删除答案。 - tonytonov
我已经知道如何对分箱数据集进行分位数计算,可以使用ApproxQuantile()函数。实际上,我会将您的答案标记为已接受,因为它将我引导到了正确的方向,即在创建数据框之前保存分位数,然后使用它们创建数据框并使用geom_vline绘制图形。我之前也有类似的想法,但没有完全理清楚。 - AF7

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