Przegląd
Jestem względnie obeznany data.table, ale nie bardzo dplyr. Przeczytałem niektóre dplyrwiniety i przykłady, które pojawiły się na SO, i jak dotąd moje wnioski są następujące:
data.tableidplyrsą porównywalne pod względem prędkości, z wyjątkiem sytuacji, gdy istnieje wiele (tj.> 10–100 tys.) grup oraz w niektórych innych okolicznościach (patrz punkty odniesienia poniżej)dplyrma bardziej dostępną składniędplyrstreszcza (lub będzie) potencjalne interakcje DB- Istnieją pewne niewielkie różnice w funkcjonalności (patrz „Przykłady / użycie” poniżej)
Moim zdaniem 2. nie ma większego znaczenia, ponieważ jestem dość dobrze z tym zaznajomiony data.table, choć rozumiem, że dla nowych użytkowników obu będzie to duży czynnik. Chciałbym uniknąć kłótni, która jest bardziej intuicyjna, ponieważ nie ma to znaczenia dla mojego konkretnego pytania zadanego z perspektywy kogoś, kogo już znasz data.table. Chciałbym również uniknąć dyskusji na temat tego, w jaki sposób „bardziej intuicyjny” prowadzi do szybszej analizy (z pewnością prawda, ale znowu nie to, co mnie najbardziej interesuje).
Pytanie
Chcę wiedzieć:
- Czy istnieją zadania analityczne, które są o wiele łatwiejsze do zakodowania w jednym lub drugim pakiecie dla osób zaznajomionych z pakietami (tj. Wymagana jest kombinacja kombinacji klawiszy w porównaniu z wymaganym poziomem ezoteryzmu, gdzie mniejsza część jest dobra).
- Czy istnieją zadania analityczne, które są wykonywane znacznie (tj. Ponad 2x) bardziej efektywnie w jednym pakiecie w porównaniu do drugiego.
Jedno ostatnie pytanie SO spowodowało, że pomyślałem o tym trochę więcej, ponieważ do tego momentu nie sądziłem, dplyrże zaoferuje coś więcej niż to, co już mogę zrobić data.table. Oto dplyrrozwiązanie (dane na końcu Q):
dat %.%
group_by(name, job) %.%
filter(job != "Boss" | year == min(year)) %.%
mutate(cumu_job2 = cumsum(job2))
Co było znacznie lepsze niż moja próba hackowania data.tablerozwiązania. To powiedziawszy, dobre data.tablerozwiązania są również całkiem dobre (dzięki Jean-Robert, Arun, i zauważcie, że faworyzowałem jedno stwierdzenie nad najbardziej optymalnym rozwiązaniem):
setDT(dat)[,
.SD[job != "Boss" | year == min(year)][, cumjob := cumsum(job2)],
by=list(id, job)
]
Składnia tego drugiego może wydawać się bardzo ezoteryczna, ale w rzeczywistości jest dość prosta, jeśli jesteś do tego przyzwyczajony data.table(tzn. Nie używa niektórych bardziej ezoterycznych sztuczek).
Idealnie chciałbym zobaczyć kilka dobrych przykładów, w których dplyrlub data.tablesposób jest znacznie bardziej zwięzły lub działa znacznie lepiej.
Przykłady
Stosowaniedplyrnie zezwala na zgrupowane operacje, które zwracają dowolną liczbę wierszy (z pytania eddi , uwaga: wygląda na to, że zostanie zaimplementowane w dplyr 0.5 , również @beginneR pokazuje potencjalne obejście przy użyciudoodpowiedzi na pytanie @ eddi).data.tableobsługuje połączenia toczne (dzięki @dholstius), a także połączenia nakładające siędata.tablewewnętrznie optymalizuje wyrażenia formieDT[col == value]lubDT[col %in% values]na prędkości poprzez automatyczną indeksowania który wykorzystuje przeszukiwanie binarne stosując taką samą składnię zasady R. Zobacz tutaj, aby uzyskać więcej szczegółów i mały test.dplyroferty standardowych wersji oceny funkcji (npregroup,summarize_each_), które mogą uprościć programową wykorzystaniadplyr(uwaga programowej użytku zdata.tablejest z pewnością możliwe, tylko wymaga starannego myśli, podstawienie / cytowania itp, przynajmniej według mojej wiedzy)
- Przeprowadziłem własne testy porównawcze i stwierdziłem, że oba pakiety są porównywalne w analizie stylu „split Apply Combine”, z wyjątkiem sytuacji, gdy istnieje bardzo duża liczba grup (> 100 KB), w których moment
data.tablestaje się znacznie szybszy. - @Arun przeprowadził testy porównawcze złączeń , pokazując, że
data.tableskaluje się lepiej niżdplyrwraz ze wzrostem liczby grup (zaktualizowane o ostatnie ulepszenia w obu pakietach i najnowszą wersję R). Test porównawczy przy próbie uzyskania unikalnych wartości jestdata.tableokoło 6 razy szybszy. - (Niezweryfikowany) ma
data.table75% szybciej na większych wersjach grupy / aplikuj / sortuj, podczas gdydplyrbył mniejszy o 40% na mniejszych ( kolejne pytanie SO z komentarzy , dzięki danas). - Matt, główny autor
data.table, jest porównywana grupowania operacji nadata.table,dplyra pytonpandasna maksymalnie 2 miliardów wierszy (~ 100GB pamięci RAM) . - Starszych grup odniesienia na 80K ma
data.table~ 8x szybciej
Dane
To jest pierwszy przykład, który pokazałem w sekcji pytań.
dat <- structure(list(id = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L), name = c("Jane", "Jane", "Jane", "Jane",
"Jane", "Jane", "Jane", "Jane", "Bob", "Bob", "Bob", "Bob", "Bob",
"Bob", "Bob", "Bob"), year = c(1980L, 1981L, 1982L, 1983L, 1984L,
1985L, 1986L, 1987L, 1985L, 1986L, 1987L, 1988L, 1989L, 1990L,
1991L, 1992L), job = c("Manager", "Manager", "Manager", "Manager",
"Manager", "Manager", "Boss", "Boss", "Manager", "Manager", "Manager",
"Boss", "Boss", "Boss", "Boss", "Boss"), job2 = c(1L, 1L, 1L,
1L, 1L, 1L, 0L, 0L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L)), .Names = c("id",
"name", "year", "job", "job2"), class = "data.frame", row.names = c(NA,
-16L))
dplyri data.tablezespoły pracują nad testami porównawczymi, więc w pewnym momencie pojawi się odpowiedź. # 2 (składnia) imO jest ściśle fałszywe, ale to wyraźnie wkracza na terytorium opinii, więc głosuję również za zamknięciem.
(d)plyrma miarę 0
dplyri plyrjeśli chodzi o składnię i jest w zasadzie główny powód, dlaczego nie lubię ich składni, jest to, że muszę nauczyć się zbyt wiele (więcej niż 1) dodatkowe funkcje (z nazwami, które nadal nie mają dla mnie sensu), pamiętajcie, co robią, jakie argumenty biorą itp. To zawsze było dla mnie wielkim odejściem od filozofii plyr.
.SD.) tajemnicze skróty . [poważnie] Myślę, że są to uzasadnione różnice projektowe, które przypadną do
dplyrto:as.data.table(dat)[, .SD[job != "Boss" | year == min(year)][, cumjob := cumsum(job2)], by = list(name, job)]