2012-01-02 94 views
40

我有一个Rdata文件包含各种物体:获得从RDATA特定对象文件

New.Rdata 
    |_ Object 1 (e.g. data.frame) 
    |_ Object 2 (e.g. matrix) 
    |_... 
    |_ Object n 

我当然可以与load('New.Rdata')加载数据帧,但是,是在那里出来仅加载一个特定对象的聪明的方式这个文件并丢弃其他人?

+1

在评论,说@DWin没有。 http://stackoverflow.com/questions/6550510/examining-contents-of-rdata-file-by-attaching-into-a-new-environment-possible – 2012-01-02 12:45:37

+1

但在所有事项-R我听从西蒙。 – 2014-10-28 20:32:42

回答

61

.RData文件没有索引(内容序列化作为一个大的成对列表)。你可以通过一个方法来通过pairlist,并只分配你喜欢的条目,但这并不容易,因为你不能在R级执行它。

但是,您可以在.RData文件简单地转换成单独序列化的每个条目,并创建索引的延迟加载数据库。好的是,按需加载:

# convert .RData -> .rdb/.rdx 
e = local({load("New.RData"); environment()}) 
tools:::makeLazyLoadDB(e, "New") 

加载数据库然后只加载索引,但不加载内容。内容加载,因为它们使用的:

lazyLoad("New") 
ls() 
x # if you had x in the New.RData it will be fetched now from New.rdb 

就像使用load(),所以你不需要污染全局工作区等

+1

但查找仍然需要通过“New.RData”的串行访问才能获得“x”,对吗?所以如果“x”在“New.RData”的末尾,可能没有时间节省?问题2:在非序列化过程通过“New.RData”时,是不是会遇到其他遇到的对象? – 2012-01-02 17:14:52

+1

不,这个查找只是在'x'的开头寻找'New.rdb'并且只加载'x'。 – 2012-01-02 17:49:05

+8

这些功能的内部机会有多少? – hadley 2012-01-03 18:08:38

10

您可以使用attach而您可以指定加载到一个环境比load它将数据对象附加到搜索路径,然后您可以复制您感兴趣的一个对象并分离.Rdata对象。

这仍然加载一切,反而是简单的比一切都加载到全局工作区(可能覆盖的东西,你不想被覆盖),那么摆脱你不想要的一切的工作。

+3

这个答案很好,但用例子会更完整,因为从搜索路径中分离.RData对象并不直观。从someFile.RData中检索'someObj'的例子:'attach('someFile.RData'); someObj < - someObj; detach('file:someFile.RData')' – C8H10N4O2 2017-06-27 13:28:19

+0

@ C8H10N4O2,你的例子很好(非常明确)。但是,如果您在默认位置(2)中附加并且在调用detach之前不附加任何其他内容,则默认值可以工作,您可以在不带任何参数的情况下调用'detach()'并将文件分离。这更快更简单;你的方法更安全。 – 2017-06-27 15:14:23

4

西蒙Urbanek的答案是非常,非常好。一个缺点是,它似乎并没有工作,如果要保存的对象太大:

tools:::makeLazyLoadDB(
    local({ 
    x <- 1:1e+09 
    cat("size:", object.size(x) ,"\n") 
    environment() 
    }), "lazytest") 
size: 4e+09 
Error: serialization is too large to store in a raw vector 

我猜,这是由于目前实施的R的限制(我有2.15。 2)而不是耗尽物理内存和交换。但是,saves包可能是某些用途的替代方案。

+1

这是更多的扩展评论,而不是答案。 – C8H10N4O2 2017-08-01 19:37:37