R: Strange behavior while saving list() with save() from function output

r

Solution

look at

> attr(ok[[1]]$terms,".Environment")
<environment: 0x9bcf3f8>
> attr(ok2[[1]]$terms,".Environment")
<environment: R_GlobalEnv>

also

> ls(envir = attr(ok[[1]]$terms,".Environment"))
[1] "i"  "k"  "tt"

so `ok` is dragging around the environment of the function with it.

Also read `?object.size`

 The calculation is of the size of the object, and excludes the
 space needed to store its name in the symbol table.

 Associated space (e.g. the environment of a function and what the
 pointer in a ‘EXTPTRSXP’ points to) is not included in the
 calculation.

For example define a `test2` and an `ok3`

test2 = function(k){
    tt = vector('list',k)
    for(i in 1:k) tt[[i]] = lm(a0~b1+b2+b3,data = data)
    rr = tt
    tt
}

ok3 <- test2(2)
save(ok3, 'ok3.RdData')

> file.info('ok3.RData')$size
[1] 5043933
> file.info('ok.RData')$size
[1] 3366005
> file.info('ok2.RData')$size
[1] 1678851

> ls(envir = attr(ok3[[1]]$terms,".Environment"))
[1] "i"  "k"  "rr" "tt"

so `ok` is roughly twice as big as `ok2` because it has the extra `tt` and `ok3` is three times as big as it has `tt` and `rr`

> c(object.size(ok),object.size(ok2),object.size(ok3))
[1] 4019336 4019336 4019336

There is related discussion here

Problem

I am currently facing a strange problem while saving lists and 'sublists' with R. The title may not be explicit but here is what is troubling me : Given some data (here the data is totaly artificial but the problem isn't the relevance of the model) : ``` set.seed(1) a0 = rnorm(10000,10,2) b1 = rnorm(10000,10,2) b2 = rnorm(10000,10,2) b3 = rnorm(10000,10,2) data = data.frame(a0,b1,b2,b3) ``` And a function returning a list of complex objects (let's say `lm()` objects) : ``` test = function(k){ tt = vector('list',k) for(i in 1:k) tt[[i]] = lm(a0~b1+b2+b3,data = data) tt } ``` Our test fonction returns a list of `lm()` objects. Lets look the size of this object : ``` ok = test(2) object.size(ok) > object.size(ok) 4019336 bytes ``` Let's create `ok2`, an exactly similar object but not within a function : ``` ok2 = vector('list',2) ok2[[1]] = lm(a0~b1+b2+b3,data = data) ok2[[2]] = lm(a0~b1+b2+b3,data = data) ``` ... and check his size : ``` > object.size(ok2) 4019336 bytes ``` Here we are, `ok` and `ok2` are exactly the same, and so tells us R. Problem, if we save these objects on hard drive as R object (with `save()` or `saveRDS()`) : ``` save(ok,file='ok.RData') save(ok2,file='ok2.RData') ``` Theirs sizes on hard drive are respectively : `3 366 005 bytes` and `1 678 851 bytes`. `ok` is 2 times bigger than `ok2` while they are exactly similar! Even more strange, if you save a 'sublist' of our objects, lets say `ok[[1]]` and `ok2[[1]]` (objects once again totaly identical) : ``` a = ok[[1]] a2 = ok2[[1]] save(a,file='console/a.RData') save(a2,file='console/a2.RData') ``` Theirs sizes on hard drive respectively : `2 523 284 bytes` and `838 977 bytes`. Two things : Why does the size of `a` differ from the size of `a2` on hard drive? Why does the size of `ok` differ from the size of `ok2` on hard drive? And why `a` which is exactly half of `ok` sizes `2 523 284 bytes` while `ok` sizes at `3 366 005 bytes` on HD?. Am I missing something? ps : I runned this test under Windows 7 32bits with R 2.15.1, 2.15.2, 2.15.3, 3.0.0, and with debian and R 2.15.1, R 2.15.2. I am having this problem every time. EDIT thx to @user1609452, here is a little trick which seems to be working : ``` test2 = function(k){ tt = vector('list',k) for(i in 1:k){ tt[[i]] = lm(a0~b1+b2+b3,data = data) attr(tt[[i]]$terms,".Environment") = .GlobalEnv attr(attr(tt[[i]]$model,"terms"),".Environment") = .GlobalEnv } tt } ``` Formula objects come with their own environment and a lot of stuff in it. Put it to `NULL` or to .GlobalEnv and it seems to be working. Functions like predict.lm() still work and our saved objects have the right size on the HD. Not sure why though.

Original source