循环内调用save()无法正确保存R对象的问题排查
R循环中save函数保存对象异常的解决方法
问题场景
正常工作的代码
x <- data.frame(x = rnorm(5e5)) save("x", file="x.Rda")
这段代码能正确生成约3.7Mb的文件,符合预期。
循环中的错误表现
当尝试在循环里保存对象(示例以单个对象测试)时:
for (i in "x") save(i, file="x.Rda")
生成的文件仅67字节,加载后得到的只是值为"x"的向量i,完全不是目标对象。
已尝试的无效写法
以下几种尝试都没能解决问题:
for (i in "x") save(i, file="x.Rda", envir = .GlobalEnv) # 仍生成67字节文件 for (i in "x") save(get(i), file="x.Rda") # 报错:找不到对象‘get(i)’ for (i in "x") save(get(i), file="x.Rda", envir = .GlobalEnv) # 报错:找不到对象‘get(i)’ for (i in "x") save(get(i, envir = .GlobalEnv), file="x.Rda") # 报错:找不到对象‘get(i, envir = .GlobalEnv)’
问题原因
save函数的参数逻辑是:如果直接传入变量名(比如save(x, ...)),它会保存该变量指向的对象;但如果传入的是字符串形式的对象名(比如save("x", ...)),它会根据字符串查找对应对象。而在循环中直接传i时,save会把循环变量i本身(即字符串"x")当作要保存的对象,而非i所指向的全局环境中的x对象。
正确解决方案
方法1:使用list参数指定对象名(推荐)
save的list参数接受字符向量,用来指定要保存的对象名称,这是处理动态对象名保存的标准方式:
for (i in "x") save(list = i, file="x.Rda")
方法2:批量保存多个对象的扩展
如果需要循环保存多个对象,比如对象名列表为c("x", "y", "z"),可以这样写:
obj_list <- c("x", "y", "z") for (obj_name in obj_list) { save(list = obj_name, file = paste0(obj_name, ".Rda")) }
这样每个对象会被单独保存到对应名称的文件中。
方法3:结合get与saveRDS(单对象场景可选)
如果只需要保存单个对象,也可以用saveRDS配合get,这种方式不需要指定对象名,直接保存对象本身:
for (i in "x") saveRDS(get(i, envir = .GlobalEnv), file="x.Rda")
加载时用readRDS("x.Rda")即可获取对象,注意这种方式只能保存单个对象。
内容的提问来源于stack exchange,提问作者Mihail
相关产品推荐
相关产品推荐

