Я только что заметил, что 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 почти для всех операций с данными, но теперь я хотел сделать это "проще" с помощью используя функции basi c :-) Но теперь я действительно удивлен, что эти функции действительно плохо работают! Кто-нибудь еще не заметил? Или я их неправильно использую?