web-dev-qa-db-fra.com

Ajouter une ligne par référence à la fin d'un objet data.table

Dans ce question le data.table le créateur du package explique pourquoi les lignes ne peuvent pas être insérées (ou supprimées) par référence au milieu a data.table encore. Il souligne également que de telles opérations pourraient être possibles en fin de tableau. Pourriez-vous montrer un code pour réaliser cette action? Ce serait la version "par référence" de

a<- data.table(id=letters[1:2], var=1:2)
> a
   id var
1:  a   1
2:  b   2
> rbind(a, data.table(id="c", var=3))
   id var
1:  a   1
2:  b   2
3:  c   3

merci.

MODIFIER:

puisqu’une solution appropriée n’est pas encore possible, laquelle des options suivantes est meilleure (si elle est différente en interne, je ne suis pas sûr) du point de vue de la vitesse et de l’utilisation de la mémoire?

rbind(a, data.table(id="c", var=3))

rbindlist(list(a,  data.table(id="c", var=3)))

existe-t-il finalement d'autres (meilleures) méthodes?

38
Michele

Pour répondre à votre modification, exécutez simplement un benchmark:

a = data.table(id=letters[1:2], var=1:2)
b = copy(a)
c = copy(b) # let's also just try modifying same value in place
            # to see how well changing existing values does
microbenchmark(a <- rbind(a, data.table(id="c", var=3)),
               b <- rbindlist(list(b,  data.table(id="c", var=3))),
               c[1, var := 3L],
               set(c, 1L, 2L, 3L))
#Unit: microseconds
#                                                  expr     min        lq    median        uq      max neval
#          a <- rbind(a, data.table(id = "c", var = 3)) 865.460 1141.2585 1357.1230 1539.4300 6814.492   100
#b <- rbindlist(list(b, data.table(id = "c", var = 3))) 260.440  325.3835  445.4190  522.8825 1143.930   100
#                                   c[1, `:=`(var, 3L)] 482.147  626.5570  778.3135  904.3595 1109.539   100
#                                    set(c, 1L, 2L, 3L)   2.339    5.677    7.5140    9.5170   19.033   100

rbindlist est clairement meilleur que rbind. Merci à Matthew Dowle de souligner les problèmes liés à l'utilisation de [ en boucle, j'ai ajouté une autre référence avec set.

De ce qui précède, vos meilleures options sont d'utiliser rbindlist, ou de dimensionner le data.table pour commencer, puis en remplissant simplement les valeurs (vous pouvez également utiliser une stratégie similaire à std::vector dans C++, et doublez la taille chaque fois que vous manquez d'espace, si vous ne connaissez pas la taille des données pour commencer, puis une fois que vous avez terminé de les remplir, supprimez les lignes supplémentaires).

22
eddi