rbindlist
est une version optimisée de do.call(rbind, list(...))
, qui est connue pour être lente lors de l'utilisationrbind.data.frame
Où excelle-t-il vraiment
Quelques questions qui montrent où se rbindlist
trouve la lumière
Fusion vectorisée rapide de la liste de données, trames par ligne
Problème lors de la conversion d'une longue liste de data.frames (~ 1 million) en data.frame unique à l'aide de do.call et ldply
Ceux-ci ont des repères qui montrent à quelle vitesse cela peut être.
rbind.data.frame est lent, pour une raison
rbind.data.frame
fait beaucoup de vérifications et correspondra par nom. (c'est-à-dire que rbind.data.frame tiendra compte du fait que les colonnes peuvent être dans des ordres différents, et correspondre par nom), rbindlist
ne fait pas ce genre de vérification et rejoindra par position
par exemple
do.call(rbind, list(data.frame(a = 1:2, b = 2:3), data.frame(b = 1:2, a = 2:3)))
## a b
## 1 1 2
## 2 2 3
## 3 2 1
## 4 3 2
rbindlist(list(data.frame(a = 1:5, b = 2:6), data.frame(b = 1:5, a = 2:6)))
## a b
## 1: 1 2
## 2: 2 3
## 3: 1 2
## 4: 2 3
Quelques autres limitations de rbindlist
Il avait du mal à gérer factors
, en raison d'un bogue qui a depuis été corrigé:
rbindlist deux data.tables où l'un a un facteur et l'autre un type de caractère pour une colonne ( bogue # 2650 )
Il a des problèmes avec les noms de colonne en double
voir
Message d'avertissement: dans rbindlist (allargs): AN introduits par coercition: bug possible dans data.table? ( Bogue n ° 2384 )
Les noms de domaine rbind.data.frame peuvent être frustrants
rbindlist
peut gérer lists
data.frames
et data.tables
, et renverra une table data.table sans noms de domaine
vous pouvez vous mêler de noms de domaine en utilisant do.call(rbind, list(...))
see
Comment éviter de renommer les lignes lors de l'utilisation de rbind dans do.call?
Efficacité de la mémoire
En termes de mémoire rbindlist
est implémentée dans C
, la mémoire est donc efficace, il utilise setattr
pour définir des attributs par référence
rbind.data.frame
est implémenté dans R
, il effectue de nombreuses affectations et utilise attr<-
(et class<-
et rownames<-
tout cela créera (en interne) des copies du data.frame créé.
attr<-
,class<-
et (je pense)rownames<-
tous modifier en place.DF = data.frame(a=1:3); .Internal(inspect(DF)); tracemem(DF); attr(DF,"test") <- "hello"; .Internal(inspect(DF))
.rbind.data.frame
a une logique de "détournement" spéciale - quand son premier argument est adata.table
, il appelle à la.rbind.data.table
place, ce qui fait un peu de vérification et appelle ensuite enrbindlist
interne. Donc, si vous avez déjà desdata.table
objets à lier, il y a probablement peu de différence de performances entrerbind
etrbindlist
.rbindlist
est capable de correspondre par noms (use.names=TRUE
) et de remplir également les colonnes manquantes (fill=TRUE
). J'ai mis à jour ceci , ceci et ce post. Cela vous dérange-t-il de le modifier ou est-ce que je peux le faire? Dans les deux cas, ça me va.dplyr::rbind_list
est également assez similaireBy
v1.9.2
,rbindlist
avait beaucoup évolué, implémentant de nombreuses fonctionnalités, notamment:En outre, dans
v1.9.2
, arbind.data.table
également gagné unfill
argument, qui permet de lier en remplissant les colonnes manquantes, implémenté dans R.Maintenant
v1.9.3
, il y a encore plus d'améliorations sur ces fonctionnalités existantes:rbind.data.frame
ralentit un peu principalement à cause des copies (ce que @mnel souligne également) qui pourraient être évitées (en passant à C). Je pense que ce n'est pas la seule raison. La mise en œuvre de la vérification / correspondance des noms de colonnes dansrbind.data.frame
pourrait également être plus lente lorsqu'il y a beaucoup de colonnes par data.frame et qu'il y a beaucoup de data.frames à lier (comme indiqué dans le benchmark ci-dessous).Cependant, ce
rbindlist
manque de certaines fonctionnalités (comme la vérification des niveaux de facteur ou la correspondance des noms) n'a qu'un poids très minime (ou pas) pour qu'il soit plus rapide querbind.data.frame
. C'est parce qu'ils ont été soigneusement implémentés en C, optimisés pour la vitesse et la mémoire.Voici un benchmark qui met en évidence la liaison efficace tout en faisant correspondre les noms de colonnes ainsi qu'en utilisant
rbindlist
lause.names
fonctionnalité dev1.9.3
. L'ensemble de données se compose de 10000 data.frames de taille 10 * 500 chacun.NB: ce benchmark a été mis à jour pour inclure une comparaison avec
dplyr
'sbind_rows
La liaison des colonnes en tant que telles sans vérifier les noms n'a pris que 1,3 alors que la vérification des noms de colonnes et la liaison appropriée ne prenaient que 1,5 seconde de plus. Par rapport à la solution de base, c'est 14 fois plus rapide et 18 fois plus rapide que
dplyr
la version de.la source