更新现有的Rdata文件
我发现自己需要更新先前使用save
创建的Rdata文件中的一个或两个数据对象。 如果我不小心加载文件,我可以忘记重新保存文件中的一些对象。 作为一个例子,我正在处理一些存储在sysdata.rda
对象(我不想导出用于内部使用的查找表),只想更新单个对象。
我还没有设法确定是否有一个标准的方法来做到这一点,所以创建了我自己的功能。
resave <- function (..., list = character(), file = stop("'file' must be specified")) {
# create a staging environment to load the existing R objects
stage <- new.env()
load(file, envir=stage)
# get the list of objects to be "resaved"
names <- as.character(substitute(list(...)))[-1L]
list <- c(list, names)
# copy the objects to the staging environment
lapply(list, function(obj) assign(obj, get(obj), stage))
# save everything in the staging environment
save(list=ls(stage, all.names=TRUE), file=file)
}
它看起来像是过度杀伤。 有没有更好/更简单的方法来做到这一点?
顺便说一下,我是否认为在函数调用的范围内创建的新环境会被销毁?
这是一个稍微缩短的版本:
resave <- function(..., list = character(), file) {
previous <- load(file)
var.names <- c(list, as.character(substitute(list(...)))[-1L])
for (var in var.names) assign(var, get(var, envir = parent.frame()))
save(list = unique(c(previous, var.names)), file = file)
}
我利用了load
函数返回加载变量的名称的事实,所以我可以使用函数的环境而不是创建一个。 当使用get
,我很小心只查看调用该函数的环境,即parent.frame()
。
这里是一个模拟:
x1 <- 1
x2 <- 2
x3 <- 3
save(x1, x2, x3, file = "abc.RData")
x1 <- 10
x2 <- 20
x3 <- 30
resave(x1, x3, file = "abc.RData")
load("abc.RData")
x1
# [1] 10
x2
# [1] 2
x3
# [1] 30
我在stackoverflow包中添加了@ flodel的重构版本的答案。 它明确使用环境更具防御性。
resave <- function(..., list = character(), file) {
e <- new.env()
load(file, e)
list <- union(list, as.character(substitute((...)))[-1L])
copyEnv(parent.frame(), e, list)
save(list = ls(e, all.names=TRUE), envir = e, file = file)
}
链接地址: http://www.djcxy.com/p/6525.html
上一篇: Updating an existing Rdata file
下一篇: Grouping functions (tapply, by, aggregate) and the *apply family