148 votes

Pourquoi rbindlist est-il "meilleur" que rbind?

Je suis en train de parcourir la documentation de data.table et j'ai également remarqué, à la suite de certaines conversations tenues ici, que SO rbindlist est censé être meilleur que rbind .

Je voudrais savoir pourquoi rbindlist meilleur que rbind et dans quels scénarios rbindlist excelle vraiment par rapport à rbind ?

Y a-t-il un avantage en termes d'utilisation de la mémoire?

164voto

mnel Points 48160

rbindlist est une version optimisée de l' do.call(rbind, list(...)), qui est connu pour être lent lors de l'utilisation d' rbind.data.frame


Où en est-elle vraiment excellent

Quelques questions qui vous indiquent rbindlist brille sont

comment fusionner une liste de données.les images en ligne

De la difficulté de la conversion à la longue liste de données.les cadres (~1 m) de données unique.cadre à l'aide de le faire.appel et ldply

Ces repères qui montrent à quelle vitesse il peut être.


rbind.les données.le cadre est lent, pour une raison

rbind.data.frame fait beaucoup de vérification, et correspondent par leur nom. (c'est à dire rbind.les données.cadre en compte le fait que les colonnes peuvent être de différents ordres, et correspondent par leur nom), rbindlist ne pas faire ce genre de vérification, et rejoindre par la poste

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 utilisé pour la lutte contre factors, en raison d'un bogue qui a depuis été corrigé:

rbindlist deux données.les tables où l'on a le facteur et d'autres ont du caractère, le type d'une colonne (Bogue #2650)

Il a des problèmes avec les noms de colonne en double

voir Message d'avertissement: dans rbindlist(allargs) : NAs introduit par la coercition: il est possible de bug dans les données.de la table? (Bogue #2384)


rbind.les données.cadre rownames peut être frustrant

rbindlist peut manipuler lists data.frames et data.tables, et sera de retour de données.table sans rownames

vous pouvez obtenir dans un méli-mélo de rownames l'aide d' do.call(rbind, list(...)) voir

Comment éviter le changement de nom de lignes lors de l'utilisation de rbind à l'intérieur de le faire.appel?


L'efficacité de mémoire

En termes de mémoire rbindlist est mis en œuvre en C, donc est efficace en terme de mémoire, il utilise setattr pour définir les attributs par référence

rbind.data.frame est mis en œuvre en R, il fait beaucoup d'attribution, et les utilisations attr<- (et class<- et rownames<- tous (en interne) pour créer des copies de la création de données.cadre.

53voto

Arun Points 41689

En v1.9.2, rbindlist a évolué un peu, la mise en œuvre de nombreuses fonctionnalités, y compris:

  • Le choix le plus haut SEXPTYPE de colonnes, en liaison mis en œuvre en v1.9.2 de clôture FR #2456 et Bug #4981.
  • Manutention factor colonnes correctement - d'abord mis en œuvre dans v1.8.10 clôture Bug #2650 et étendu à la liaison commandé facteurs avec soin en v1.9.2 ainsi, la fermeture de FR #4856 et Bug #5019.

De plus, en v1.9.2, rbind.data.table également gagné une fill argument, qui permet de se lier par le remplissage des colonnes manquantes, mis en œuvre dans R.

Maintenant, en v1.9.3, il y a encore plus d'améliorations sur ces caractéristiques:

  • rbindlist de gains en un argument use.names, qui par défaut est FALSE pour la compatibilité ascendante.
  • rbindlist gagne également un argument fill, qui par défaut est également FALSE pour la compatibilité ascendante.
  • Ces caractéristiques sont mises en œuvre en C, et écrit avec soin afin de ne pas compromettre la vitesse, tandis que l'ajout de fonctionnalités.
  • Depuis rbindlist peut maintenant correspondre à des noms et remplir les colonnes manquantes, rbind.data.table seulement des appels rbindlist maintenant. La seule différence est qu' use.names=TRUE par défaut pour rbind.data.table, pour assurer la compatibilité ascendante.

rbind.data.frame ralentit un peu surtout en raison de copies (@mnel souligne ainsi) qui pourraient être évités (en se déplaçant à C). Je pense que ce n'est pas la seule raison. La mise en œuvre de la vérification/correspondance des noms de colonne en rbind.data.frame pourrait obtenir aussi plus lent quand il y a beaucoup de colonnes par les données.cadre et il ya beaucoup de ces données.les trames de liaison (comme indiqué dans la référence ci-dessous).

Cependant, qu' rbindlist manque(ed) certaines fonctions (comme la vérification des niveaux de facteur ou de la correspondance des noms) porte très petits (ou pas) poids vers elle d'être plus rapide que l' rbind.data.frame. C'est parce qu'ils ont été soigneusement mis en œuvre en C, optimisé pour la vitesse et la mémoire.

Voici un test qui met en évidence l'efficacité de la liaison, tout en répondant aux noms des colonnes en utilisant rbindlists' use.names disposent d' v1.9.3. L'ensemble de données se compose de 10000 données.images de taille 10*500.

require(data.table)
set.seed(1L)
names = paste0("V", 1:500)
cols = 500L
foo <- function() {
    data = as.data.frame(setDT(lapply(1:cols, function(x) sample(10))))
    setnames(data, sample(names))
}
n = 10e3L
ll = vector("list", n)
for (i in 1:n) {
    .Call("Csetlistelt", ll, i, foo())
}

system.time(ans1 <- rbindlist(ll))
#   user  system elapsed
#  3.419   0.278   3.718

system.time(ans2 <- rbindlist(ll, use.names=TRUE))
#   user  system elapsed
#  5.311   0.471   5.914

system.time(ans3 <- do.call("rbind", ll))
#     user   system  elapsed
# 1097.895 1209.823 2438.452 

identical(ans2, setDT(ans3)) # [1] TRUE

Liaison des colonnes en tant que tel, sans vérification de noms pris en 3,7 secondes où la vérification de noms de colonnes et de liaison dûment pris seulement 1,2 secondes de plus. Par rapport à la solution de base, c'est >400 fois plus rapide.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X