在R/R-Studio中加载和保存单个对象到工作空间

10
我喜欢使用工作区的想法。到目前为止,我总是保存整个工作区并将其全部加载到现有项目中。但很多时候,我只需要从指定的工作区中获取单个对象。是否有可能将它们分别从另一个工作区加载?
此外,有时将对象添加到已有的工作区中会很方便。例如,假设您有五个巨大的脚本,每个脚本都有一个巨大的工作区,并且您不想混合它们以使它们都在一个工作区中。那么现在,您想将每个工作区的干净结果仅存储到另一个干净的工作区中...
这些是基本任务:
# save entire workspace
save.image("mypath/myworkspace")

# load entire workspace
load ("mypath/myworkspace")

# save a single object (or several)
save (myobject,file="mypath/myworkspace")

# load a single object from an existing workspace
?

# add a single object to an existing workspace
?

2
不是回答您的问题(想不出解决方案),但您可以考虑将数据组织成列表而不是工作区。然后根据需要使用 attach(list) 和 detach(list) 来获取来自不同项目/子项目的对象。当然,您随时可以从任何列表访问单个对象。 - ndoogan
我想到了?saveRDS - Roland
@ Roland。我尝试了你的提示,但我认为它在R-Studio中存在问题。我收到了一个错误消息,这也在这里讨论:http://support.rstudio.org/help/discussions/problems/318-error-bad-restore-file-magic-number - Joschi
2个回答

17

RStudio把globalenv()称为你的“工作区”

你可以将.RData文件加载到除globalenv()以外的其他环境中

x <- 1; y <- 2 #First, create some objects
save.image()  # save workspace to disk
rm(list=ls()) # remove everything from workspace
tmp.env <- new.env() # create a temporary environment
load(".RData", envir=tmp.env) # load workspace into temporary environment
x <- get("x", pos=tmp.env) # get the objects you need into your globalenv()
#x <- tmp.env$x # equivalent to previous line
rm(tmp.env) # remove the temporary environment to free up memory

一旦一个对象出现在你的globalenv(),它将显示在RStudio的“工作区”选项卡中。

同样地,你可以将对象分配到环境中。

tmp.env <- new.env()
load(".RData", envir=tmp.env) # load workspace into temporary environment
assign("z", 10, pos=tmp.env)
#tmp.env$z <- 10 # equivalent to previous line

如果您告诉save它们的位置,现在可以将所有对象保存在tmp.env中。

save(list=ls(all.names=TRUE, pos=tmp.env), envir=tmp.env, file="test.RData")
rm(tmp.env)

您已经成功地将一个对象z添加到存储在test.RData中的工作区中。

rm(list=ls(all.names=TRUE))
load("test.RData")

> ls()
[1] "x"       "y"       "z"  

3

#从一个已存在的工作区加载单个对象

您无法从工作区恢复一个对象。因为save.image(".Rdata")只是save(list = ls(all=TRUE), file= ".RData")的简化命令。当您使用load命令时,将还原那个列表中的所有对象。

但是,您可以将几个合并在一个列表中的对象保存然后加载它们。例如:

library(ggplot2)
c <- ggplot(mtcars, aes(factor(cyl)))
d<-c + geom_bar(width=.5)  # create two graphs 
c<- c + geom_bar()
save(list=c("c","d"),file="myobjects") # save them (notice that objects are accessed as strings)
rm(list = ls()) # remove from the memory
load(file="myobjects") # load again

你现在已经得到了你的对象(图表)c和d,这回答了你最后的问题。

现在,假设你已经在文件myobjects中有了对象c和d,并且你想要向该文件添加更多对象。如果不加载它,就不可能实现,因为save和saveRDS会将数据压缩存储(对于save,您会得到tar包,在saveRDS中,您可以选择压缩方法)。正如您所知,您无法将数据添加到已归档的文件中而不解压缩它。我能看到的唯一解决方案是这样的。假设我们想将a和b添加到myobjects中。

library(ggplot2)
a<-qplot(rnorm(100))
b<-qplot(rnorm(200))
list=ls()
list<-list[-which(list%in%c("a","b"))] # list all variables except the one you want to save
rm(list=list) # we're deleting all except a and b
load(file="myobjects") # loading or unpacking objects c and d
save(list=ls(),file="myobjects") # saving objects a,b,c,d in myobjects file

这是一个粗略的解决方法,但是如果你考虑一下,在R中我们有数据或图形对象(我使用ggplot2示例的原因)。数据可以保存为save.table,图形可以存储到grobs列表中(使用gridExtra包),然后使用save保存。


1
这似乎是海报已经知道如何做的事情(请参见发布的代码中的第三个保存示例)。 - ndoogan
考虑到加载示例中没有代码以及对象加载演示,我认为你的论点至少是非常值得怀疑的。从文件中添加新对象,这正是代码所做的,仔细阅读。 - user974514
1
其实ndoogan是对的。我的意思是,我也可以像第三行下面发布的那样保存多个对象,就像这样:save (myobject1,myobject2,etc.,file="mypath/myworkspace")。实际上,在保存对象之前没有必要先制作列表。上面的问题更多地涉及向已有工作区添加单个对象(不会通过覆盖而失去其它对象)或从现有工作区检索单个对象,而无需完全加载它。 - Joschi
此外,rm(list) 将删除名为 list 的对象。你的意思是写成 rm(list=list) - GSee
@GSee 谢谢您的编辑。您的解决方案同样很好,但是一旦您有大型数据集,保持几个环境可能会在内存短缺方面带来很大问题。 - user974514

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接