在保存R对象时重命名该对象

7
我正在寻找一种方法在R中以不同的名称“即时”save()变量。以下是我想要实现的示例:
AAA = 1
BBB = 2
XXX = 3
YYY = 4
save(AAA=XXX, BBB=YYY, file="tmp.Rdat")  
# does NOT save a variable AAA to file with value 3 in it, which is the aim...

基本上,我希望save()函数能够将XXX的值保存到一个名为AAA的变量下。请注意,这不是关于重命名变量的问题:我当然可以在保存之前重命名变量XXX,例如AAA = XXX,然后save(AAA, ..., file=...),但这当然会破坏代码中AAA的值。
显然的方法是创建临时变量,然后恢复其值:
AAA = 1
BBB = 2
XXX = 3
YYY = 4
AAAtmp = AAA; BBBtmp = BBB      # record values of AAA, BBB
AAA = XXX; BBB = YYY
save(AAA, BBB, file="tmp.Rdat")
AAA = AAAtmp; BBB = BBBtmp      # restore values of AAA, BBB

... 但是每个人都会同意这很混乱(尤其是涉及到更多的变量时)。

这一直困扰着我,我的感觉是函数 save() 不能实现我想要的功能。所以我猜我将不得不更新我的代码,并走向使用不同的保存函数(例如 saveRDS())的道路。

谢谢您的帮助!


你能解释一下为什么要这样做吗?看起来saveRDS可能更适合你想要的... - Dason
@Dason:没有什么特别的原因,只是我编写代码的方式:有时候我需要将一个给定的变量保存在工作区中已经存在的名称下(例如,保存一个临时变量并使其“看起来”像是非临时变量)。这在过去几次中出现过,每次我都试图解决这个问题,但都没有成功。所以这一次我决定向专家们请教... :) - Eric Lehmann
4个回答

10

这证明比我预想的要棘手一些。我会很感兴趣看到其他人会想出什么,并且也想知道对我的解决方案是否有任何异议。

saveit <- function(..., file) {
  x <- list(...)
  save(list=names(x), file=file, envir=list2env(x))
}

foo <- 1
saveit(bar=foo, file="hi.Rdata")

1
是的,这似乎完美地按预期工作。最重要的是,它允许在“另一端”使用load(),这意味着我不必更新实际使用保存数据的所有代码片段(例如使用saveRDS()/readRDS()的情况)。但是,我仍然需要为此解决方案定义一个新的函数saveit()... 在我原始帖子中的测试中,将其内置到save()函数本身中会很好。 - Eric Lehmann

1

对Aaron答案的可能有帮助的补充:

如果您想使用先前定义的字符串作为文件名保存和加载文件,请考虑对Aaron(非常酷!)答案进行以下小修改:

model_name <- "model1"

saveit <- function(..., string, file) {
        x <- list(...)
        names(x) <- string
        save(list=names(x), file=file, envir=list2env(x))
    }

fit <- somemodelingfunc(...)

saveit(fit = fit, string = model_name, file=paste(model_name, ".RData", sep=""))

这将增加功能性,因为您可以直接传递文件名作为字符串,而无需直接使用变量。如果您的保存和加载需要具有依赖于上下文的特定名称,则这非常有用。例如,我的用例是模型拟合,我只在文件开头定义模型名称,但不需要修改脚本中的任何其他内容。我还没有在R中看到更简单的方法来实现这一点...

如何使用此函数保存多个变量?例如,一个向量vec = seq(1,100,1),以及两个标量值a = 0.1和b = 12,每个都有一个单独的新名称。 - Gab
你好Gab!你尝试使用purrr包中的任一map变体了吗? - Marco Wirthlin
你好,Marco,感谢你的回答。我尝试安装purrr包,使用命令:devtools::install_github("tidyverse/purrr"),但是出现了以下错误:
library(purrr) Error in value[3L] : Package ‘purrr’ version 0.3.4 cannot be unloaded: Error in unloadNamespace(package) : namespace ‘purrr’ is imported by ‘usethis’, ‘tidyselect’, ‘modelr’, ‘broom’, ‘tidyr’ so cannot be unloaded. 我可能做错了什么?如何正确安装purrr包?
- Gab
我会做以下事情:
  1. 确保有一个干净的工作环境:重新启动RStudio。
  2. install.packages("purrr")
  3. 我建议从这里开始:https://jennybc.github.io/purrr-tutorial/ls01_map-name-position-shortcuts.html
如果您在使用map时遇到问题,请告诉我如何使saveit函数正常工作。
- Marco Wirthlin

1
比定义一个函数更快的方法是,您可以创建一个local环境:
local({
    AAA <- XXX
    BBB <- YYY
    save(AAA, BBB, file="tmp.Rdat")  
})

因为您在不同的环境中工作和分配任务,所以不需要存储临时变量,这些变量仍将在全局环境中保持完好无损:

> AAA
[1] 1
> BBB
[1] 2

0
我发现可以使用“get”函数创建一个列表,并将环境中的所有对象分配给列表的每个元素,然后可以重命名列表的每个元素。
另一种方法可能是使用“get”函数和“assign”函数。
objectNames <- ls(all.names=T)
res <- list()
for (o in objectNames) {
    res[[paste(prefix,o,sep="_")]] <- get(o)
}
format(object.size(res), units="Gb")

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