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

时间:2020-09-27 19:45:04

标签: r ggplot2 probability-density

假设我有一个非常大的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))

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

1 个答案:

答案 0 :(得分:2)

您可以在数据库侧使用足够小的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