r - 当按两个变量分组时,tapply() 和 acast() 非常慢且占用内存
问题描述
我刚刚注意到,tapply()
当reshape2::acast()
按两个变量分组时,在场景中超级慢且消耗内存!
看这个例子:
#download data and functions for monitoring time & memory
download.file("http://artax.karlin.mff.cuni.cz/~ttel5535/pub/so/tapply,reshape2_slow/tapply,reshape_slow.Rdata", "tapply,reshape_slow.Rdata", mode="wb")
load(file = "tapply,reshape_slow.Rdata")
require(reshape2)
mstart()
xx <- acast(bb, fi ~ gi, sum, value.var = "hour")
mstop()
# user system elapsed
# 6.58 0.79 7.90
#max memory used: 911.2Mb.
令人惊讶的是非常缓慢和内存贪婪!只是为了显示数据的属性:
nrow(bb)
#[1] 9467
dim(xx)
#[1] 4850 1492
print(object.size(xx), units = "Mb")
#28 Mb
现在tapply()
:
mstart()
xx2 <- tapply(bb$hour, list(bb$fi, bb$gi), sum, default = 0)
mstop()
# user system elapsed
# 6.45 2.36 9.44
#max memory used: 1135.9Mb.
更慢,更贪内存!
现在,比较一下,当分组是由 SQLite 完成时的解决方案,并且 acast() 仅用于重塑:
require(sqldf)
mstart()
xx3_0 <- sqldf("select fi, gi, sum(hour) as sum from bb group by fi, gi")
xx3 <- acast(xx3_0, fi ~ gi, fill = 0, value.var = "sum")
mstop()
# user system elapsed
# 0.22 0.05 0.28
#max memory used: 174.1Mb.
通常,我对几乎所有数据操作都使用 sqldf,但现在我想通过使用基本函数使其“更容易”:-) 但现在我真的很惊讶这些函数的性能非常糟糕!还没有人注意到吗?还是我用错了?
解决方案
推荐阅读
- variables - 如何读取 txt 文件并使用其数据与其他变量进行比较?
- javascript - 如何使用 ...spread 获取作为函数中参数的函数的“返回”?
- c# - 如何检查 IMobileServiceTableQuery
是否为空 - schema.org - 为我的多语言 Web 应用程序定义 Schema.org JSON-LD
- javascript - 如何在 Href 中使用 Javascript 变量
- r - 带有 rstudio 的新版本 R
- android - AppBarLayout / CollapsingToolbarLayout 被底部导航重叠
- javascript - redux store 更改时更新列表
- javascript - 上传到heroku后移动@media查询不起作用
- java - Spring Data JPA 在通过 ManyToOne 急切获取时不设置字段