Kiedy należy używać operatora: = w data.table?

88

data.tableobiekty mają teraz operator: =. Co sprawia, że ​​ten operator różni się od wszystkich innych operatorów przypisania? Jakie są jego zastosowania, o ile jest szybszy i kiedy należy go unikać?

Ari B. Friedman
źródło

Odpowiedzi:

94

Oto przykład pokazujący 10 minut skróconych do 1 sekundy (z WIADOMOŚCI na stronie głównej ). Jest to podobne do przypisania do a, data.frameale nie kopiuje za każdym razem całej tabeli.

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 )

Umieszczenie tego :=w jten sposób pozwala na więcej idiomów:

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

i :

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

Nie przychodzi mi do głowy żaden powód, żeby go unikać :=! Poza tym wewnątrz forpętli. Ponieważ :=pojawia się w środku DT[...], wiąże się z niewielkim narzutem[.data.table metody; np S3 wysyłka i sprawdzanie obecności i rodzaju argumentów, takich jak i, by, nomatchitp więc dla wewnątrz forpętli, jest niski narzut, bezpośredni wersja :=nazywa set. Zobacz ?setwięcej szczegółów i przykładów. Wady setinclude, które imuszą być numerami wierszy (bez wyszukiwania binarnego) i nie można ich łączyć z by. Wprowadzenie tych ograniczeń setmoże radykalnie zmniejszyć koszty ogólne.

system.time(for (i in 1:1000) set(DT,i,"V1",i))
     user  system elapsed 
    0.016   0.000   0.018
Matt Dowle
źródło
26
Dziękujemy za opracowanie tego pakietu. Mam wrażenie, że poprawię dużo mojego kodu, aby używać tego pakietu.
Iterator
1
Na czacie poproszono mnie o samodzielne zadawanie pytań / udzielanie odpowiedzi (co najwyraźniej jest zalecane ) - to pytanie jest tutaj
Matt Dowle,
4
@MatthewDowle Chcesz dołączyć wyjaśnienie, kiedy nie używać: = i zamiast tego używać set ()?
Ari B. Friedman
2
@MatthewDowle, gdybym mógł, dałbym +1 ponownie.
Ari B. Friedman
3
@jabberwocky Nie ma problemu. set(DT, i, "V1", i)ustawia "V1"kolumnę, podczas gdy set(DT, i, colVar, i)ustawia nazwę kolumny zawartą w colVarzmiennej (np. jeśli colVar = "V1"zostało zrobione wcześniej). Cudzysłowy wskazują, że należy traktować nazwę kolumny dosłownie, zamiast wyszukiwać zmienną.
Matt Dowle