Hi!
Für viele verschiedene Gruppen in by
ist shift
viel langsamer als manuelles Schalten.
Siehe: http://stackoverflow.com/questions/35179911/shift-in-data-table-v1-9-6-is-slow-for-many-groups
und https://github.com/nachti/datatable_test/blob/master/leadtest.R für ein detailliertes Beispiel.
Beifall,
Gerhard
Das ist nicht überraschend. Dies verschwindet, wenn gforce
für :=
optimiert ist. Es steht auf der Liste für diese Veröffentlichung, glaube ich.
+1 für diese Leistungssteigerung. shift()
ist der größte Engpass in einem Großteil meines Codes. Scheint, dass bei einer festen Anzahl von Zeilen die Zeit zum Ausführen von shift()
proportional zur Anzahl der Gruppen in den Daten ist.
library(data.table)
# Build table to store timings
timings <- CJ(RowCount = 10^7, Groups = 10^c(0:7))
timings[, SizePerGroup := RowCount/Groups]
# Loop through each experiment
for(i in 1:nrow(dt)){
print(paste0("Iteration: ", i))
# Build dataset
timings_i <- timings[i]
dt <- data.table(Grp = rep(seq_len(timings_i$Groups), each = timings_i$SizePerGroup))
dt[, Value := sample(100, size = .N, replace = T)]
# Measure the time it takes to insert a column indicating the previous value by group
elapsed <- system.time(dt[, PrevValueByGrp := shift(Value, type = "lag"), by = Grp])["elapsed"]
timings[i, Elapsed := elapsed]
}
library(ggplot2)
ggplot(timings, aes(x = Groups, y = Elapsed))+geom_line()+geom_point()
@ ben519 Fyi, für den Sonderfall, wenn Ihr Code so aussieht, gibt es eine Verknüpfung:
library(data.table)
dt <- data.table(Grp = rep(seq_len(1e6), each=10L))
dt[, Value := sample(100L, size = .N, replace = TRUE)]
system.time(dt[, PrevValueByGrp := shift(Value, type = "lag"), by = Grp][])
# user system elapsed
# 19.50 0.80 20.34
system.time(dt[, v := shift(Value, type = "lag")][rowid(Grp)==1L, v := NA][])
# user system elapsed
# 1.00 0.87 1.25
dt[, all.equal(v, PrevValueByGrp)]
# [1] TRUE
Hilfreichster Kommentar
@ ben519 Fyi, für den Sonderfall, wenn Ihr Code so aussieht, gibt es eine Verknüpfung: