如何使用walk()或walk2()保存临时.RData文件
解决方法:修正新增行保存逻辑并优化函数
首先,咱们先理清你遇到的核心问题:walk() 函数是用来**遍历迭代对象(比如列表、向量)**的,但你的new_rows是单个dataframe,完全不需要遍历,直接用saveRDS()或者save()就能完成保存操作。另外还有几个小细节需要调整,我把完整的优化后的函数写出来,再逐一解释:
library(dplyr) library(stringr) fun <- function(df1, df2){ # 先检查两个数据框是否完全一致 if(identical(df1, df2)){ stop("No new updated rows") } else { # 更高效的方式:直接找出df2中不在df1的行 new_rows <- anti_join(df2, df1) # 提取新增行的数量(避免返回tibble,直接拿数值) n_new <- nrow(new_rows) print(str_c("there are ", n_new, " new rows")) # 1. 确保项目目录下的temp文件夹存在,不存在则创建 temp_dir <- "./temp/" if(!dir.exists(temp_dir)){ dir.create(temp_dir, recursive = TRUE, showWarnings = FALSE) } # 2. 拼接文件名:日期+下划线+文件名,避免格式混乱 file_path <- paste0(temp_dir, Sys.Date(), "_new_rows.rds") # 3. 保存单个dataframe用saveRDS(如果要存多个对象用save) saveRDS(new_rows, file = file_path) # 可选:返回保存的路径,方便后续函数调用 return(invisible(file_path)) } }
关键修改点说明:
- 替换
walk()为直接调用saveRDS():walk()是purrr包的遍历工具,适合处理多个元素的迭代场景,单个dataframe直接调用保存函数即可,完全不需要遍历。 - 优化新增行的识别逻辑:用
anti_join(df2, df1)直接筛选出df2中不存在于df1的行,比bind_rows再filter的方式更高效、更直观。 - 修复新增行数量的显示问题:原代码中
count()返回的是一个tibble,直接print会显示表格结构,改用nrow(new_rows)或者count() %>% pull(n)提取纯数值,输出更友好。 - 处理文件夹存在性:先检查
./temp/文件夹是否存在,不存在则自动创建,避免保存时因路径不存在报错。 - 规范文件名格式:在日期和文件名之间加下划线(
_),避免出现类似20240520new_rows.RData这种混乱的文件名,同时saveRDS()建议用.rds作为后缀(如果要用save()存RData格式,把后缀改成.RData即可)。
运行示例:
mt_1 <- mtcars[1:4, ] # 修正原代码的语法问题,明确取前4行 mt_2 <- mtcars[1:10, ] fun(mt_1, mt_2) # [1] "there are 6 new rows"
运行后,你就能在项目目录的temp文件夹里找到当天日期命名的新增行文件了,后续函数可以用readRDS(file_path)来读取这个文件。
内容的提问来源于stack exchange,提问作者Corey Pembleton
相关产品推荐
相关产品推荐

