Übersicht
Ich bin relativ vertraut mit data.table
, nicht so sehr mit dplyr
. Ich habe einige dplyr
Vignetten und Beispiele durchgelesen, die auf SO aufgetaucht sind, und meine bisherigen Schlussfolgerungen sind folgende:
data.table
unddplyr
sind in Bezug auf Geschwindigkeit vergleichbar, außer bei vielen (d.h. >10-100K) Gruppen und in einigen anderen Umständen (siehe Benchmarks unten)dplyr
hat eine zugänglichere Syntaxdplyr
abstrahiert potenzielle DB-Interaktionen (oder wird es tun)- Es gibt einige geringfügige funktionale Unterschiede (siehe "Beispiele/Verwendung" unten)
In meinen Augen hat Punkt 2. nicht viel Gewicht, weil ich ziemlich vertraut mit data.table
bin, obwohl ich verstehe, dass es für Benutzer, die mit beiden neu sind, ein großer Faktor sein wird. Ich würde gerne eine Diskussion darüber vermeiden, welches intuitiver ist, da das für meine spezifische Frage aus der Perspektive von jemandem, der bereits mit data.table
vertraut ist, irrelevant ist. Ich möchte auch eine Diskussion darüber vermeiden, wie "intuitiver" zu einer schnelleren Analyse führt (sicherlich wahr, aber auch das ist nicht das, worauf ich hier am meisten interessiert bin).
Frage
Was ich wissen möchte ist:
- Gibt es analytische Aufgaben, die für Personen, die mit den Paketen vertraut sind, mit einem Paket einfacher zu codieren sind als mit dem anderen (d.h. irgendeine Kombination von erforderlichen Tastenkombinationen gegen erforderlichem Maß an Esoterik, wobei weniger von beidem eine gute Sache ist).
- Gibt es analytische Aufgaben, die mit einem Paket gegenüber einem anderen wesentlich effizienter durchgeführt werden (d.h. mehr als 2x).
Eine neue SO-Frage hat mich dazu etwas mehr nachdenken lassen, weil ich bis zu diesem Zeitpunkt nicht gedacht habe, dass dplyr
viel bieten würde, was ich nicht bereits in data.table
machen könnte. Hier ist die dplyr
Lösung (Daten am Ende der Frage):
dat %.%
group_by(name, job) %.%
filter(job != "Boss" | year == min(year)) %.%
mutate(cumu_job2 = cumsum(job2))
Was viel besser war als mein Versuch einer data.table
Lösung. Das gesagt, gute data.table
Lösungen sind auch sehr gut (vielen Dank an Jean-Robert, Arun, und hier sei angemerkt, dass ich hier eine einzelne Anweisung der streng optimalen Lösung vorgezogen habe):
setDT(dat)[,
.SD[job != "Boss" | year == min(year)][, cumjob := cumsum(job2)],
by=list(id, job)
]
Die Syntax für letzteres mag sehr esoterisch erscheinen, ist aber eigentlich ziemlich einfach, wenn man mit data.table
vertraut ist (d.h. es werden keine der esoterischeren Tricks verwendet).
Im Idealfall würde ich gerne einige gute Beispiele sehen, bei denen die dplyr
oder data.table
Methode wesentlich prägnanter ist oder deutlich besser abschneidet.
Beispiele
Verwendung
dplyr
erlaubt keine gruppierten Operationen, die eine beliebige Anzahl von Zeilen zurückgeben (aus eddi's Frage, Anmerkung: anscheinend wird dies in dplyr 0.5 implementiert, auch zeigt @beginneR in der Antwort auf eddi's Frage einen potenziellen Workaround unter Verwendung vondo
).data.table
unterstützt rollende Joins (danke @dholstius) sowie Überlappungsjoinsdata.table
optimiert intern Ausdrücke der FormDT[col == value]
oderDT[col %in% values]
für Geschwindigkeit durch automatische Indizierung, die binäre Suche verwendet, während sie die gleiche Basis-R-Syntax verwendet. Hier finden Sie einige weitere Details und einen kleinen Benchmark.dplyr
bietet Standardbewertungsversionen von Funktionen (z.B.regroup
,summarize_each_
), die die programmatische Verwendung vondplyr
erleichtern können (Anmerkung: die programmatische Verwendung vondata.table
ist definitiv möglich, erfordert jedoch etwas Überlegung, Substitution/Quoting, etc, zumindest nach meinem Wissen)
Benchmarks
- Ich habe eigene Benchmarks durchgeführt und festgestellt, dass beide Pakete in der "Split-Apply-Combine"-Analyse vergleichbar sind, außer bei sehr großen Gruppenzahlen (>100K), ab denen
data.table
deutlich schneller wird. - @Arun führte einige Benchmarks zu Joins durch, die zeigen, dass
data.table
bei steigender Anzahl von Gruppen besser skaliert alsdplyr
(aktualisiert mit den neuesten Verbesserungen in beiden Paketen und der aktuellen Version von R). Ebenfalls ein Benchmark, bei dem versucht wurde, eindeutige Werte zu erhalten, hatdata.table
etwa 6x schneller. - (Nicht überprüft) hat
data.table
75% schneller bei größeren Versionen einer Gruppen/Anwenden/Sortieren, währenddplyr
bei den kleineren 40% schneller war (eine weitere SO-Frage aus den Kommentaren, danke danas). - Matt, der Hauptautor von
data.table
, hat Benchmarks zu Gruppenoperationen aufdata.table
,dplyr
und pythonpandas
an bis zu 2 Milliarden Zeilen (~100GB im RAM) durchgeführt. - Ein älterer Benchmark mit 80K Gruppen hat
data.table
etwa 8x schneller.
Daten
Dies gilt für das erste Beispiel, das ich im Fragenteil gezeigt habe.
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))