Vue d'ensemble
Je suis relativement familier avec data.table
, pas tellement avec des dplyr
. J'ai lu quelques - dplyr
des vignettes et des exemples qui ont sauté, et pour l'instant, mes conclusions sont les suivantes:
-
data.table
etdplyr
sont comparables en matière de vitesse, sauf quand il y a beaucoup (c'est à dire >10-100K) des groupes, et dans certaines autres circonstances (voir les repères ci-dessous) -
dplyr
a plus accessibles de syntaxe -
dplyr
résumés (ou la volonté), le potentiel de DB interactions - Il y a quelques petites différence de fonctionnalité (voir "Exemples d'Utilisation" ci-dessous)
Dans mon esprit 2. ne pas porter beaucoup de poids parce que je suis assez familier avec elle, data.table
, même si je comprends que pour les nouveaux utilisateurs à la fois, il va être un facteur important. Je voudrais éviter un argument à propos de ce qui est plus intuitive, qui n'est pas pertinente pour ma question posée du point de vue de quelqu'un qui est déjà familier avec data.table
. Je tiens également à éviter une discussion sur la façon dont "plus intuitive" conduit à une analyse plus rapide (certainement vrai, mais encore une fois, pas ce que je suis le plus intéressé à ce sujet ici).
Question
Ce que je veux savoir, c'est:
- Existe-il d'analyse des tâches qui sont beaucoup plus facile à code avec l'un ou l'autre paquet pour les personnes familières avec les paquets (par exemple, une combinaison de frappes nécessaires contre niveau requis de l'ésotérisme, où les moins de chacun est une bonne chose).
- Existe-il d'analyse des tâches qui sont effectuées de façon substantielle (c'est à dire plus que 2x) de manière plus efficace dans un seul paquet contre l'autre.
Une récente DONC, la question m'a fait penser à ceci un peu plus, parce que jusque-là, je ne pense pas qu' dplyr
offrirait bien au-delà de ce que je peux déjà faire dans data.table
. Voici l' dplyr
solution (données à la fin de la Q):
dat %.%
group_by(name, job) %.%
filter(job != "Boss" | year == min(year)) %.%
mutate(cumu_job2 = cumsum(job2))
Ce qui était beaucoup mieux que mon hack tentative d' data.table
de la solution. Cela dit, bon data.table
solutions sont également très bon (merci Jean-Robert, Arun, et de noter ici j'ai appuyé d'un état unique sur le plan strictement solution optimale):
setDT(dat)[,
.SD[job != "Boss" | year == min(year)][, cumjob := cumsum(job2)],
by=list(id, job)
]
La syntaxe de ce dernier peut sembler très ésotérique, mais il est en fait assez simple si vous avez l'habitude d' data.table
(c'est à dire ne pas utiliser certains des plus ésotériques de trucs).
Idéalement, ce que j'aimerais voir, c'est quelques bons exemples ont été l' dplyr
ou data.table
moyen est nettement plus concis ou effectue beaucoup mieux.
Exemples
L'utilisation de la
-
dplyr
ne permet pas regroupés opérations de retour nombre arbitraire de lignes (à partir de eddi la question, remarque: cela ressemble, il sera mis en œuvre dans dplyr 0.3.1, également, @débutant montre un potentiel de travail autour de l'aide d'do
dans la réponse à @eddi la question). -
data.table
prend en charge roulement joint (merci @dholstius) ainsi que le chevauchement des jointures -
data.table
en interne optimise les expressions de la formeDT[col == value]
ouDT[col %in% values]
de la vitesse par le biais de l'indexation automatique qui utilise le binaire de recherche tout en utilisant la même base de R de la syntaxe. Voir ici pour plus de détails et un minuscule indice de référence. -
dplyr
offre de série les versions d'évaluation des fonctions (par exemple,regroup
,summarize_each_
) qui permet de simplifier la programmation de l'utilisation dedplyr
(note programmatique de l'utilisation dedata.table
est certainement possible, il faut juste quelques attention tout de même, la substitution/devis, etc, au moins à ma connaissance)
Repères
- J'ai couru mes propres repères et a trouvé les deux packages pour être comparable au "split appliquer une combinaison de style de l'analyse, sauf quand il y a un très grand nombre de groupes (>100K)
data.table
devient considérablement plus rapide. - @Arun couru quelques repères sur les jointures, montrant qu'
data.table
échelles de mieux qu'dplyr
lorsque le nombre de groupes augmentation (mis à jour avec des améliorations récentes dans les emballages et les dernières version de R). Aussi, un point de référence lorsque vous essayez d'obtenir des valeurs uniques adata.table
~6x plus rapide. - (Non vérifiées) a
data.table
75% plus rapide sur de plus grandes versions d'un groupe/appliquer/trier toutdplyr
a 40% plus rapide sur les plus petites (une autre DONC, la question de commentaires, merci danas). - Matt, l'auteur principal de l'
data.table
, a comparé regroupement des opérations surdata.table
,dplyr
pythonpandas
sur jusqu'à 2 milliards de lignes (~100 GO de RAM). - Une des plus anciennes de référence sur 80K groupes a
data.table
~8x plus rapide
Données
C'est pour le premier exemple que j'ai montré dans la section question.
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))