Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating a new variable with get(data.table) directly after loading data.table object

Tags:

r

data.table

I am trying to generate a new variable in a data.table which I generated, saved and loaded again. After loading I adress the data.table indirectly through get() and this does not work for generating a new variable as long as I dont adress it directly for variable creation before. Possibly it is some kind of environment issue?

# Generate data.table
t<-data.table(x=c(1,2,3,4))
tStr<-"t"
names(t)

# Generate Variable a -> ok
get(tStr)[, a:=1]
names(t)

# Generate Variable b -> ok
t[, b:=1]
names(t)

# Save
save(t, file="test.Robj")
load("test.Robj", .GlobalEnv)

# Generate Variable c -> fails 
get(tStr)[, c:=1] 
names(t)

# Generate Variable d -> ok
t[, d:=1]
names(t)

# Generate Variable e -> ok again !?
get(tStr)[, e:=1]
names(t)

Thanks for your help

like image 919
ibedi score Avatar asked Jul 19 '26 14:07

ibedi score


1 Answers

This is because important meta data does not survive the storage action:

> t<-data.table(x=c(1,2,3,4))
> attr(t, ".internal.selfref")
<pointer: 0x0000000000100788>
> save(t, file="test.Robj")
> load("test.Robj", .GlobalEnv)
> attr(t, ".internal.selfref")
<pointer: (nil)>
> t[, d:=1]
> attr(t, ".internal.selfref")
<pointer: 0x0000000000100788>

Notice how you lose the memory pointer. I'm not sure this is so much a bug as an inherent conflict between what a data.table is and what save does. It seems in order for this to work properly we would need a special load method that re-assigns the internal pointer on loading data.table objects.

In this case, using the modify by reference seems to reset the pointer.

EDIT: as a workaround in your use case, you can try:

t <- data.table(x=c(1,2,3,4))
save(t, file="test.Robj")
load("test.Robj", .GlobalEnv)
assign("t", get("t")[, c:=3])
t

which works as expected:

   x c
1: 1 3
2: 2 3
3: 3 3
4: 4 3

Also note that expecting:

get("t")[, c:=3]

will work is a little bit like expecting that:

get("x") <- 5

will work. data.table might in the future add this feature, but it you're treading in this murky area where the reference nature of data.table really starts conflicting with the R semantics.

like image 110
BrodieG Avatar answered Jul 22 '26 05:07

BrodieG



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!