tapply () и acast () очень медленные и занимают много памяти при группировании по двум переменным - PullRequest
0 голосов
/ 07 января 2020

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

...