我目前在使用 R 保存列表和“子列表”时遇到了一个奇怪的问题。标题可能不明确,但让我感到困扰的是:
给定一些数据(这里的数据是完全人为的,但问题不在于模型的相关性):
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)
还有一个返回复杂对象列表的函数(比如说lm()
对象):
test = function(k){
tt = vector('list',k)
for(i in 1:k) tt[[i]] = lm(a0~b1+b2+b3,data = data)
tt
}
我们的测试函数返回一个lm()
对象列表。让我们看看这个对象的大小:
ok = test(2)
object.size(ok)
> object.size(ok)
4019336 bytes
让我们创建ok2
一个完全相似但不在函数内的对象:
ok2 = vector('list',2)
ok2[[1]] = lm(a0~b1+b2+b3,data = data)
ok2[[2]] = lm(a0~b1+b2+b3,data = data)
...并检查他的大小:
> object.size(ok2)
4019336 bytes
我们在这里,ok
并且ok2
完全相同,因此告诉我们 R。问题,如果我们将这些对象保存在硬盘驱动器上作为 R 对象(使用save()
or saveRDS()
):
save(ok,file='ok.RData')
save(ok2,file='ok2.RData')
它们在硬盘上的大小分别是:3 366 005 bytes
和1 678 851 bytes
。
ok
比ok2
它们完全相似时大 2 倍!
更奇怪的是,如果您保存我们对象的“子列表”,可以说ok[[1]]
和ok2[[1]]
(对象再次完全相同):
a = ok[[1]]
a2 = ok2[[1]]
save(a,file='console/a.RData')
save(a2,file='console/a2.RData')
它们在硬盘上的大小分别为:2 523 284 bytes
和838 977 bytes
。
两件事:为什么大小与硬盘驱动器的大小a
不同?a2
为什么硬盘的大小与硬盘的大小ok
不同?ok2
为什么哪个尺寸 a
正好是HDok
尺寸2 523 284 bytes
的一半?ok
3 366 005 bytes
我错过了什么吗?
ps:我在 Windows 7 32bits 下使用 R 2.15.1、2.15.2、2.15.3、3.0.0 以及 debian 和 R 2.15.1、R 2.15.2 运行了这个测试。我每次都遇到这个问题。
编辑
谢谢@user1609452,这里有一个小技巧,似乎很有效:
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
}
公式对象带有自己的环境和很多东西。将它放入NULL
或放入 .GlobalEnv ,它似乎正在工作。predict.lm() 之类的函数仍然有效,并且我们保存的对象在 HD 上具有正确的大小。不知道为什么。