Pregunta Agregue una fila por referencia al final de un objeto data.table


En esto pregunta el data.table El creador del paquete explica por qué las filas no se pueden insertar (o eliminar) por referencia en el medio. data.table todavía. También señala que tales operaciones podrían ser posibles al final de la mesa. ¿Podría mostrar un código para perfome esta acción? Sería la versión "por referencia" 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

Gracias.

EDITAR:

dado que aún no es posible una solución adecuada, ¿cuál de las siguientes opciones es mejor (si es internamente diferente, no está seguro) ya sea desde una perspectiva de uso de velocidad y memoria?

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

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

¿Hay finalmente otros (mejores) métodos?


32
2018-05-28 12:23


origen


Respuestas:


Para responder a su edición, simplemente ejecute un punto de referencia:

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 es claramente mejor que rbind. Gracias a Matthew Dowle señalando los problemas con el uso [ en un ciclo, agregué otro punto de referencia con set.

De lo anterior, tus mejores opciones están usando rbindlisto dimensionando data.table para empezar y luego solo llenar los valores (también puede usar una estrategia similar a std::vector en C++, y duplique el tamaño cada vez que se quede sin espacio, si no conoce el tamaño de los datos para empezar, y luego, una vez que termine de completarlos, elimine las filas adicionales).


18
2018-05-28 16:49