R:大数据集的直方图

Posted

技术标签:

【中文标题】R:大数据集的直方图【英文标题】:R: Histogram with large data set 【发布时间】:2018-04-24 21:18:52 【问题描述】:

目标

从data.frame d,我正在尝试制作由bpInPiece 加权的cMPerSite 列的直方图。换句话说,bpInPiece 是每个cMPerSite 值的观察次数。

Y 轴应代表密度,X 轴应为对数刻度。

尝试

我可以做类似的事情(可以通过为x 预先分配内存大小来改进)。

x = c()
for (row in 1:nrow(d))

    x = c(x, rep(d$cMPerSite[row],d$bpInPiece[row]))

hist(x,breaks=100, freq=FALSE)

但是当数据太多(我的完整数据集中有大约 1000 万行)时,这变得完全不切实际,因为x 变得太大而无法存储在 RAM 中。另外,我认为把 X 轴放在对数刻度上肯定有点混乱。

或者,我会认为我可以做到

ggplot(d) + geom_histogram(aes(x = cMPerSite, y=bpInPiece), stat="identity") + scale_x_log10() + theme_classic(25)
Warning: Ignoring unknown parameters: binwidth, bins, pad

但是,由于某种我不明白的原因,没有显示任何内容。另外,我不确定如何将 Y 轴放在密度而不是计数中。

我认为 bin 大小应该随着 X 轴的变化而对数变化,但这让我感到困惑,因为它会导致 bin 收集“人为”的大量观察值。不确定直方图通常如何使用对数刻度 X 轴显示。请注意,ggplot(d) + geom_histogram(aes(x = cMPerSite, y=bpInPiece), stat="identity") 也不显示任何内容,因此问题不仅仅是 X 轴上的对数比例问题。

你能帮我制作这个直方图吗?

我的数据子集

structure(list(chrom = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), end = c(241608, 
612298, 715797, 956634, 983330, 1190613, 1236417, 1330208, 1391915, 
1464000, 1911436, 1913462, 2092038, 2169783, 2354812, 2363639, 
2544241, 2551672, 2575287, 2589721, 2659117, 2884565, 3037319, 
3100967, 3152276, 4319658, 4335072, 6301896, 6550219, 6596684, 
7132319, 7435267, 7469158, 7604030, 7937619, 8131876, 9359659, 
9598491, 9945959, 10262757, 10392172, 10646861, 10816847, 11094415, 
11360199, 11964985, 12220179, 12222166, 12389943), cMInPiece = c(0, 
1e-07, 1e-07, 0.7118558, 9.99999999473644e-08, 0.9540829, 9.99999998363421e-08, 
0.4967211, 1.244988, 0.2137991, 8.808171, 0.500545200000001, 
1.5721302, 1.6856566, 2.2552469, 1.0000000116861e-07, 2.6973586, 
0.355113100000001, 0.355233800000001, 1.0000000116861e-07, 1.4903822, 
2.8174978, 1.0000000116861e-07, 0.355231, 1.0000000116861e-07, 
8.2735924, 0.425817699999996, 6.4568106, 0.372779399999999, 0.363684999999997, 
0.181640399999999, 0.177473599999999, 1.0000000116861e-07, 0.177463800000005, 
0.355294099999995, 1.0000000116861e-07, 1.6101482, 1.0000000116861e-07, 
0.533477099999999, 0.355287800000006, 9.99999940631824e-08, 1.0000000116861e-07, 
1.0000000116861e-07, 1.0000000116861e-07, 1.0000000116861e-07, 
1.0000000116861e-07, 9.99999940631824e-08, 1.0000000116861e-07, 
1.0000000116861e-07), bpInPiece = c(241608, 370690, 103499, 240837, 
26696, 207283, 45804, 93791, 61707, 72085, 447436, 2026, 178576, 
77745, 185029, 8827, 180602, 7431, 23615, 14434, 69396, 225448, 
152754, 63648, 51309, 1167382, 15414, 1966824, 248323, 46465, 
535635, 302948, 33891, 134872, 333589, 194257, 1227783, 238832, 
347468, 316798, 129415, 254689, 169986, 277568, 265784, 604786, 
255194, 1987, 167777), cMPerSite = c(1e-16, 2.69767190914241e-13, 
9.66192910076426e-13, 2.95575762860358e-06, 3.74587953054257e-12, 
4.60280341369046e-06, 2.18321543612659e-12, 5.29604226418313e-06, 
2.01757985317711e-05, 2.96593049871679e-06, 1.96858790977928e-05, 
0.000247060809476802, 8.80370374518411e-06, 2.16818650717088e-05, 
1.21886131363192e-05, 1.13288774406491e-11, 1.49353750235324e-05, 
4.77880635176962e-05, 1.50427186110523e-05, 6.92808654348135e-12, 
2.14764856764078e-05, 1.24973288740641e-05, 6.54647349127419e-13, 
5.58118086978381e-06, 1.94897583598608e-12, 7.08730509807415e-06, 
2.76253860127155e-05, 3.28286140498591e-06, 1.50118756619403e-06, 
7.82707414182711e-06, 3.39112268615754e-07, 5.85821989252278e-07, 
2.95063589650969e-12, 1.31579423453352e-06, 1.06506539484214e-06, 
5.14781970114898e-13, 1.31142734506016e-06, 4.18704366117646e-13, 
1.53532728193675e-06, 1.1214963478305e-06, 7.72707909154135e-13, 
3.92635728942395e-13, 5.88283747888707e-13, 3.60272081683082e-13, 
3.76245376578762e-13, 1.65347744770232e-13, 3.91858719496471e-13, 
5.03271269092148e-11, 5.96029260080999e-13)), .Names = c("chrom", 
"end", "cMInPiece", "bpInPiece", "cMPerSite"), row.names = c(NA, 
-49L), class = "data.frame")

【问题讨论】:

您正试图在 for loop 中增长 x,这是非常低效的。更多信息在这里r-statistics.co/Strategies-To-Improve-And-Speedup-R-Code.html & winvector.github.io/Accumulation 首选 bin 大小是多少? log10 == 1?你想和bpInPiece 相加吗?或者计算bpInPiece的每次出现? @CPak 我想 bin 大小应该随着 X 轴的变化而对数变化,但这让我感到困惑,因为它会导致 bin 收集“人工”大量观察值。不确定直方图通常如何使用对数刻度 X 轴显示。请注意,ggplot(d) + geom_histogram(aes(x = cMPerSite, y=bpInPiece), stat="identity") 也不显示任何内容,因此问题不仅仅是 X 轴上的对数比例问题。在cMPerSite 的每个 bin 中,条形的高度应该代表bpInPiece 的总和。我或多或少地回答了你的问题吗? 这与 [graph] 标签有什么关系?你知道那个标签是用于数学图表,而不是图表,对吧? 其实graph标签是指图形、图表和数据的显示。 【参考方案1】:

这可能会让你开始

假设您的数据太大而无法一步处理 - 想法是手动生成直方图,它本质上是每个 bin 的观察次数

1) 将您的 data.frame 拆分为内存可管理的大小 - N 可以是任意数字

    N <- 10
    L <- split(df, cut(seq_len(nrow(df)), breaks=N))

2) 对于每个拆分

每个组的总和 bpInPiece - i %&gt;% group_by(G = floor(-log10(cMPerSite))) %&gt;% summarise(sum=sum(bpInPiece)) 然后聚合所有拆分 - %&gt;% group_by(G) %&gt;% summarise(sum = sum(sum))

然后绘图 - ggplot(...)

library(tidyverse)
counts <- map_df(L, function(i)  i %>% group_by(G = floor(-log10(cMPerSite))) %>% summarise(sum=sum(bpInPiece)) ) %>%
             group_by(G) %>% summarise(sum = sum(sum)) %>%
             ggplot(., aes(G, sum)) + geom_col()
counts

【讨论】:

以上是关于R:大数据集的直方图的主要内容,如果未能解决你的问题,请参考以下文章

如何在 R 中绘制预分箱直方图

R中的高效方法是将新列添加到具有大数据集的数据框中

【R语言】--- 直方图

使用非常大的数据集分析 R 中两点之间的空间数据

在 R 中处理大型数据集

Lesson 1 数据集的建立