R - hist(XX, plot=FALSE)$count 的更快替代品
R - faster alternative to hist(XX, plot=FALSE)$count
我正在寻找 R 的 hist(x, breaks=XXX, plot=FALSE)$count
函数的更快替代品,因为我不需要生成的任何其他输出(因为我想在 sapply
中使用它调用,需要调用此函数的 100 万次迭代),例如
x = runif(100000000, 2.5, 2.6)
bincounts = hist(x, breaks=seq(0,3,length.out=100), plot=FALSE)$count
有什么想法吗?
第一次尝试使用 table
和 cut
:
table(cut(x, breaks=seq(0,3,length.out=100)))
它避免了额外的输出,但在我的电脑上大约需要 34 秒:
system.time(table(cut(x, breaks=seq(0,3,length.out=100))))
user system elapsed
34.148 0.532 34.696
与 hist
的 3.5 秒相比:
system.time(hist(x, breaks=seq(0,3,length.out=100), plot=FALSE)$count)
user system elapsed
3.448 0.156 3.605
使用tabulate
和.bincode
运行速度比hist
快一点:
tabulate(.bincode(x, breaks=seq(0,3,length.out=100)), nbins=100)
system.time(tabulate(.bincode(x, breaks=seq(0,3,length.out=100))), nbins=100)
user system elapsed
3.084 0.024 3.107
使用 tablulate
和 findInterval
相对于 table
和 cut
提供了显着的性能提升,并且相对于 hist
有不错的改进:
tabulate(findInterval(x, vec=seq(0,3,length.out=100)), nbins=100)
system.time(tabulate(findInterval(x, vec=seq(0,3,length.out=100))), nbins=100)
user system elapsed
2.044 0.012 2.055
看来最好的办法就是削减 hist.default
的所有开销。
nB1 <- 99
delt <- 3/nB1
fuzz <- 1e-7 * c(-delt, rep.int(delt, nB1))
breaks <- seq(0, 3, by = delt) + fuzz
.Call(graphics:::C_BinCount, x, breaks, TRUE, TRUE)
我通过 运行 debugonce(hist.default)
对此进行了缩减,以确切了解 hist
的工作原理(并使用较小的向量进行测试 - n = 100
而不是1000000
).
比较:
x = runif(100, 2.5, 2.6)
y1 <- .Call(graphics:::C_BinCount, x, breaks + fuzz, TRUE, TRUE)
y2 <- hist(x, breaks=seq(0,3,length.out=100), plot=FALSE)$count
identical(y1, y2)
# [1] TRUE
我正在寻找 R 的 hist(x, breaks=XXX, plot=FALSE)$count
函数的更快替代品,因为我不需要生成的任何其他输出(因为我想在 sapply
中使用它调用,需要调用此函数的 100 万次迭代),例如
x = runif(100000000, 2.5, 2.6)
bincounts = hist(x, breaks=seq(0,3,length.out=100), plot=FALSE)$count
有什么想法吗?
第一次尝试使用 table
和 cut
:
table(cut(x, breaks=seq(0,3,length.out=100)))
它避免了额外的输出,但在我的电脑上大约需要 34 秒:
system.time(table(cut(x, breaks=seq(0,3,length.out=100))))
user system elapsed
34.148 0.532 34.696
与 hist
的 3.5 秒相比:
system.time(hist(x, breaks=seq(0,3,length.out=100), plot=FALSE)$count)
user system elapsed
3.448 0.156 3.605
使用tabulate
和.bincode
运行速度比hist
快一点:
tabulate(.bincode(x, breaks=seq(0,3,length.out=100)), nbins=100)
system.time(tabulate(.bincode(x, breaks=seq(0,3,length.out=100))), nbins=100)
user system elapsed
3.084 0.024 3.107
使用 tablulate
和 findInterval
相对于 table
和 cut
提供了显着的性能提升,并且相对于 hist
有不错的改进:
tabulate(findInterval(x, vec=seq(0,3,length.out=100)), nbins=100)
system.time(tabulate(findInterval(x, vec=seq(0,3,length.out=100))), nbins=100)
user system elapsed
2.044 0.012 2.055
看来最好的办法就是削减 hist.default
的所有开销。
nB1 <- 99
delt <- 3/nB1
fuzz <- 1e-7 * c(-delt, rep.int(delt, nB1))
breaks <- seq(0, 3, by = delt) + fuzz
.Call(graphics:::C_BinCount, x, breaks, TRUE, TRUE)
我通过 运行 debugonce(hist.default)
对此进行了缩减,以确切了解 hist
的工作原理(并使用较小的向量进行测试 - n = 100
而不是1000000
).
比较:
x = runif(100, 2.5, 2.6)
y1 <- .Call(graphics:::C_BinCount, x, breaks + fuzz, TRUE, TRUE)
y2 <- hist(x, breaks=seq(0,3,length.out=100), plot=FALSE)$count
identical(y1, y2)
# [1] TRUE