Когда мне следует использовать оператор: = в data.table? - PullRequest
83 голосов
/ 11 августа 2011

data.table объекты теперь имеют оператор: =. Чем этот оператор отличается от всех других операторов присваивания? Кроме того, для чего он нужен, насколько он быстрее и когда его следует избегать?

1 Ответ

89 голосов
/ 11 августа 2011

Вот пример, показывающий, что 10 минут сокращены до 1 секунды (из NEWS на homepage ).Это все равно, что присвоить data.frame, но не копировать всю таблицу каждый раз.

m = matrix(1,nrow=100000,ncol=100)
DF = as.data.frame(m)
DT = as.data.table(m)

system.time(for (i in 1:1000) DF[i,1] <- i)
     user  system elapsed 
  287.062 302.627 591.984 

system.time(for (i in 1:1000) DT[i,V1:=i])
     user  system elapsed 
    1.148   0.000   1.158     ( 511 times faster )

Вставка := в j, например, позволяет использовать больше идиом:

DT["a",done:=TRUE]   # binary search for group 'a' and set a flag
DT[,newcol:=42]      # add a new column by reference (no copy of existing data)
DT[,col:=NULL]       # remove a column by reference

и:

DT[,newcol:=sum(v),by=group]  # like a fast transform() by group

Я не могу придумать никаких причин, чтобы избежать :=!Кроме, внутри for петли.Поскольку := появляется внутри DT[...], это сопровождается небольшими издержками метода [.data.table;например, S3 отправляет и проверяет наличие и тип аргументов, таких как i, by, nomatch и т. д. Поэтому для внутренних циклов for существует небольшая служебная, прямая версия :=, называемая set.Смотрите ?set для более подробной информации и примеров.Недостатки set заключаются в том, что i должны быть номерами строк (без двоичного поиска), и вы не можете комбинировать его с by.Эти ограничения set могут значительно снизить накладные расходы.

system.time(for (i in 1:1000) set(DT,i,"V1",i))
     user  system elapsed 
    0.016   0.000   0.018
...