Prezentare generală
Sunt relativ familiarizat cu data.table
, nu atât de mult cu dplyr
. Am citit câteva dplyr
vignete și exemple care au apărut pe SO și, până acum, concluziile sunt ca:
data.table
șidplyr
sunt comparabile ca viteză, cu excepția cazului în care există multe grupuri (adică >10-100K) și în alte circumstanțe (a se vedea benchmark-urile de mai jos)dplyr
are o sintaxă mai accesibilădplyr
retrage (sau va) potențialele interacțiuni DB- Există câteva diferențe minore de funcționalitate (consultați „Exemple/Utilizare” de mai jos)
În mintea mea 2. nu suportă prea multă greutate pentru că sunt destul de familiarizat cu el data.table
, deși înțeleg că pentru utilizatorii nou la ambele va fi un factor important. Aș dori să evit un argument despre care este mai intuitiv, deoarece este irelevant pentru întrebarea mea specifică adresată din perspectiva cuiva familiarizat cu data.table
. De asemenea, aș dori să evit o discuție despre modul în care „mai intuitiv” duce la o analiză mai rapidă (cu siguranță adevărat, dar din nou, nu ceea ce mă interesează cel mai mult aici).
Întrebare
Ce vreau sa stiu este:
- Există sarcini analitice care sunt mult mai ușor de codat cu unul sau altul pachet pentru persoanele familiarizate cu pachetele (adică o combinație de apăsări de taste necesare vs. nivelul necesar de ezoterism, unde mai puțin din fiecare este un lucru bun).
- Există sarcini analitice care sunt efectuate substanțial (adică mai mult de 2 ori) mai eficient într-un pachet față de altul.
O întrebare SO recentă m-a pus pe gânduri la asta un pic mai mult, pentru că până în acel moment nu credeam că dplyr
va oferi mult mai mult decât pot face deja în data.table
. Iată soluția dplyr
(date de la sfârșitul Q):
dat %.%
group_by(name, job) %.%
filter(job != "Boss" | year == min(year)) %.%
mutate(cumu_job2 = cumsum(job2))
Ceea ce a fost mult mai bun decât încercarea mea de hack la o soluție data.table
. Acestea fiind spuse, soluțiile bune data.table
sunt, de asemenea, destul de bune (mulțumesc Jean-Robert, Arun și rețineți că aici am preferat afirmația unică față de soluția strict cea mai optimă):
setDT(dat)[,
.SD[job != "Boss" | year == min(year)][, cumjob := cumsum(job2)],
by=list(id, job)
]
Sintaxa pentru acesta din urmă poate părea foarte ezoteric, dar de fapt este destul de simplă dacă ești obișnuit cu data.table
(adică nu folosești unele dintre trucurile mai ezoterice).
În mod ideal, ceea ce aș dori să văd sunt câteva exemple bune în care modul dplyr
sau data.table
este substanțial mai concis sau are performanțe substanțial mai bune.
Exemple
Usagedplyr
nu permite operațiuni grupate care returnează un număr arbitrar de rânduri (de la întrebarea lui Eddi, notă: se pare că va fi implementată în dplyr 0.5, de asemenea, @beginneR arată o posibilă soluție folosinddo
în răspunsul la întrebarea lui @eddi).data.table
acceptă uniuni rulante (mulțumesc @dholstius) precum și uniuni suprapusedata.table
optimizează intern expresiile de formaDT[col == value]
sauDT[col %in% values]
pentru viteză prin indexarea automată care utilizează căutarea binară în timp ce utilizează aceeași sintaxă R de bază. Vezi aici pentru mai multe detalii și un punct de referință mic.dplyr
oferă versiuni standard de evaluare a funcțiilor (de exemplu,regroup
,summarize_each_
) care pot simplifica utilizarea programatică a luidplyr
(rețineți că utilizarea programatică a luidata.table
este cu siguranță posibilă, necesită doar o gândire atentă, înlocuire/citare etc., cel puțin din cunoștințele mele)
- Am rulat propii mei benchmarkuri și a constatat că ambele pachete sunt comparabile în analiza stilului „split apply combine”, cu excepția cazului în care există un număr foarte mare de grupuri (>100K), moment în care
data.table
devine substanțial mai rapid. - @Arun a rulat câteva benchmark-uri la îmbinări, arătând că
data.table
se scalează mai bine decâtdplyr
pe măsură ce numărul de grupuri crește (actualizat cu îmbunătățiri recente în ambele pachete și versiunea recentă a R). De asemenea, un etalon atunci când încercați să obțineți valori unice aredata.table
~6x mai rapid. - (Neverificat) are
data.table
75% mai rapid la versiunile mai mari ale unui grup/aplicare/sortare, în timp cedplyr
a fost cu 40% mai rapid la versiunile mai mici (o altă întrebare SO din comentarii, mulțumesc danas). - Matt, autorul principal al cărții
data.table
, a operațiuni de grupare comparative pedata.table
,dplyr
și pythonpandas
pe până la 2 miliarde de rânduri (~100 GB în RAM). - Un Etalonul de referință mai vechi pentru grupuri de 80.000 are
data.table
~8x mai rapid
Date
Acesta este primul exemplu pe care l-am arătat în secțiunea de întrebări.
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))
dplyr
este:as.data.table(dat)[, .SD[job != "Boss" | year == min(year)][, cumjob := cumsum(job2)], by = list(name, job)]
- person eddi   schedule 29.01.2014dplyr
șidata.table
lucrează la puncte de referință, așa că un răspuns va fi acolo la un moment dat. #2 (sintaxă) imO este strict falsă, dar asta se aventurează în mod clar pe teritoriul opiniei, așa că votez și eu pentru închidere. - person eddi   schedule 29.01.2014(d)plyr
are măsura 0 - person eddi   schedule 29.01.2014dplyr
suficient de bine pentru a o exclude și eram curios dacă cineva ar veni cu un contraexemplu bun. De asemenea, o simplă simplificare a formulăriidata.table
. - person BrodieG   schedule 29.01.2014plyr
șidata.table
și a fost, de asemenea, închis. Răspunsul meu de acolo explică mai mult de ce. - person Brian Diggs   schedule 29.01.2014data.table
are măsura 0, dar asta nu este în contradicție cu credința ta ;) - person hadley   schedule 29.01.2014data.table
la sfârșit? Și (repetând, probabil, evidentul afirmat în altă parte), cum rămâne cu dimensiunile de date mai interesante (unde aș defini interesant ca ceva care durează mai mult decât un minut în bază - care este, în general, principalul motiv pentru care oamenii încep să exploreze punctele de referință ale pachetelor)? - person eddi   schedule 30.01.2014dplyr
, cât și laplyr
în ceea ce privește sintaxa și este, practic, principalul motiv pentru care nu-mi place sintaxa lor, este că trebuie să învăț mult prea multe (a citi mai mult de 1) funcții suplimentare (cu nume că tot nu au sens pentru mine), amintește-ți ce fac, ce argumente iau, etc. Asta a fost întotdeauna o mare înfrângere pentru mine de la filozofia plyr. - person eddi   schedule 30.01.2014.SD
). [serios] Cred că acestea sunt diferențe legitime de design care vor atrage diferiți oameni - person hadley   schedule 30.01.2014.SD
et al - asta e corect -.SD
mi-a luat puțin timp să înțeleg, dar până am ajuns acolo, eram deja capabil să fac multe, în timp ce (d)plyr vă prezintă o barieră mare chiar în față. - person eddi   schedule 30.01.2014dplyr
șidata.table
. - person danas.zuokas   schedule 31.01.2014data.table
este mult mai puțin verbos decât cadrul de date standard și majoritatea operațiunilor sunt mai rapide. Te obligă să gândești cu mentalitate vectorială (care are performanțe mai bune). Îl văd ca un bun înlocuitor al cadrului de date. Sintaxa nu este intuitivă la început, dar odată ce ați ajuns să o utilizați, este ceva ușor de reținut. Văddplyr
ca un set de funcții, dardata.table
ca un nou obiect de clasă cu performanțe mult mai bune și sintaxă concisă decât cadrul tradițional de date. - person David Leal   schedule 15.03.2017