来自汇总/汇总数据的图密度

问题描述

假设我有一个非常大的SQL数据库,并且我想为一个float /数字列中的值创建一个密度图。我可以导入R中的所有值并轻松绘制密度。但是,由于该表有很多行,因此我想避免导入所有值,而是在SQL服务器上使用查询来计算摘要统计信息(例如,最小值,q25,中位数,q75,最大值),并且仅导入这几个摘要值,导致流量减少很多。

因此,在R中,我将获得类似agg对象的数据:

require(data.table)

# test data
set.seed(1234)
vec = rgamma(1000,shape = 0.75)
dt = data.table(group = 'A',val = vec)
agg = dt[,.(min = min(val),q25 = quantile(val,.25),med = median(val),q75 = quantile(val,.75),max = max(val)) ]

如何使用{ggplot2}包从此类汇总数据构建密度或小提琴图?我假设geom_density()无论如何都是在幕后计算出来的,但是我无法直接将它们输入到函数中。

我想仅通过使用agg对象来检索这样的图形:

require(ggplot2)
ggplot(dt) +
  geom_density(aes(x = val))

旁注:另一种方法是仅导入值的样本。

解决方法

您可以在数据库侧使用足够小的bin对数据进行分组和统计,导出(小得多的)汇总数据,然后重建密度图。这里的“足够小”意味着足够小,以至于数据的实际分布与汇总数据的估计分布之间的差异足够小,对于您的目标无关紧要。

您可能需要尝试一下,因为它取决于密度变化的范围。在下面的示例中,我使用了10,000个bin,这仍然是从数据库导出的相对较小的数据集。请注意,我已将您的vec样本数据扩展到一百万个值:

require(tidyverse)
require(patchwork) # Needed only for laying out the two plots
require(data.table)

# test data
set.seed(1234)
vec = rgamma(1e6,shape = 0.75) 
dt = data.table(group = 'A',val = vec)
agg = dt[,.(min = min(val),q25 = quantile(val,.25),med = median(val),q75 = quantile(val,.75),max = max(val)) ]

# Set breaks for aggregrating
br = seq(min(vec),max(vec),length.out=10000)
dx = median(diff(br))

# Aggregate data
agg2 = dt %>% 
  count(val = cut(val,breaks=br,labels=(br + dx)[-length(br)],include.lowest=TRUE),val = as.numeric(as.character(val)))

p = ggplot(data=dt,aes(val)) +
  geom_density(size=1,colour="blue",n=2^11) +
  geom_density(data=agg2 %>% uncount(weight=n),colour="orange",n=2^11) +
  theme_bw() 

p + {p + coord_cartesian(xlim=c(0,0.3))}

左侧图将实际数据的密度图与从汇总到10,000个bin中的数据重建的密度进行比较。右侧图在x轴上放大到仅接近零的细峰区域。注意出色的重叠。

enter image description here

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...