Agregar nuevas columnas a una referencia de data.table dentro de una función que no siempre funciona

Al escribir un paquete que se basa endata.tableHe descubierto un comportamiento extraño. Tengo una función que elimina y reordena alguna columna por referencia, y funciona bien, lo que significa quedata.table Pasé fue modificado sin asignar la salida de la función. Tengo otra función que agreganuevo columnas sin embargo, pero esos cambios no siempre persisten en eldata.table que fue aprobada

Aquí hay un pequeño ejemplo:

library(data.table)  # I'm using 1.9.4
test <- data.table(id = letters[1:2], val=1:2)
foobar <- function(dt, col) {
    dt[, (col) := 1]
    invisible(dt)
}

test
#  id val
#1: a   1
#2: b   2
saveRDS(test, "test.rds")
test2 <- readRDS("test.rds")
all.equal(test, test2)
#[1] TRUE
foobar(test, "new")
test
#  id val new
#1: a   1   1
#2: b   2   1
foobar(test2, "new")
test2
#  id val
#1: a   1
#2: b   2

¿Que pasó? Que hay de diferentetest2? Puedo modificar las columnas existentes en el lugar en:

foobar(test, "val")
test
#  id val new
#1: a   1   1
#2: b   1   1
foobar(test2, "val")
test2
#  id val
#1: a   1
#2: b   1

Pero agregando atest2 todavía no funciona:

foobar(test2, "someothercol")
.Last.value
#  id val someothercol
#1: a   1            1
#2: b   1            1
test2
#  id val
#1: a   1
#2: b   1

No puedo precisar todos los casos en los que veo este comportamiento, pero guardar y leer desde RDS es el primer caso que puedo replicar de manera confiable. Escribir y leer desde un CSV no parece tener el mismo problema.

¿Es este un problema de puntero alaeste problema, como serializar un data.table destruye los punteros sobreasignados? ¿Hay una manera simple de restaurarlos? ¿Cómo podría verificarlos dentro de mi función, para poder restaurar los punteros o el error si la operación no funciona?

Sé que puedo asignar la salida de la función como una solución, pero eso no es muydata.table-y ¿No crearía eso también una copia temporal en la memoria?

Respuesta a la solución de Arun

Arun ha instruido que de hecho es un problema de puntero, que se puede diagnosticar contruelength y arreglado consetDT oalloc.col. Me encontré con un problema encapsulando su solución en una función (continuando desde el código anterior):

func <- function(dt) {if (!truelength(dt)) setDT(dt)}
func2 <- function(dt) {if (!truelength(dt)) alloc.col(dt)}
test2 <- readRDS("test.rds")
truelength(test2)
#[1] 0
truelength(func(test2))
#[1] 100
truelength(test2)
#[1] 0
truelength(func2(test2))
#[1] 100
truelength(test2)
#[1] 0

Por lo tanto, parece que la copia local dentro de la función se está modificando correctamente, pero la versión de referencia no. Por qué no?

Respuestas a la pregunta(1)

Su respuesta a la pregunta