You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言如何跨不同文件夹批量对文件应用统一处理函数

问题描述

我数年前开始接触R语言,它在数据框清洗、数据准备及其他基础任务处理场景中十分便捷实用。
目前我需要用R对存储在不同文件夹下的大量文件执行统一的基础处理操作:自动遍历dataset_2006、dataset_2007两个文件夹,完成shapefile合并、csv合并、表关联筛选、结果导出的全流程,替代现有重复编写的脚本。
现有重复逻辑的脚本如下:

library(dplyr)
library(readr)
library(sf)
library(purrr)

setwd("C:/Users/Downloads/global_data/dataset_2006")

shp2006 <- list.files(pattern = 'data_2006.*\\.shp$',  full.names = TRUE) 
listOfShp <- lapply(shp2006, st_read)
combinedShp <- do.call(what = sf:::rbind.sf, args=listOfShp)

#import and merge CSV files into one data frame
folderfiles <- list.files(pattern = 'csv_2006_.*\\.csv$', full.names = TRUE) 

csv_data <- folderfiles %>% 
  set_names() %>% 
  map_dfr(.f = read_delim,
          delim = ";",
          .id = "file_name")

new_shp_2006 <- merge(combinedShp, csv_data , by = "ID") %>% filter(label %in% c("AR45T", "GK879"))
   
st_write(new_shp_2006 , "new_shp_2006.shp", overwrite = TRUE)




setwd("C:/Users/Downloads/global_data/dataset_2007")

shp2007 <- list.files(pattern = 'data_2007.*\\.shp$',  full.names = TRUE) 
listOfShp <- lapply(shp2007, st_read)
combinedShp <- do.call(what = sf:::rbind.sf, args=listOfShp)

#import and merge CSV files into one data frame
folderfiles <- list.files(pattern = 'csv_2007_.*\\.csv$', full.names = TRUE) 

csv_data <- folderfiles %>% 
  set_names() %>% 
  map_dfr(.f = read_delim,
          delim = ";",
          .id = "file_name")

new_shp_2007 <- merge(combinedShp, csv_data , by = "ID") %>% filter(label %in% c("AR45T", "GK879"))
   
st_write(new_shp_2007 , "new_shp_2007.shp", overwrite = TRUE)
优化实现

核心思路是把单年份的处理逻辑封装为通用函数,避免反复修改工作目录、重复编写相同逻辑,后续新增处理年份只需要往配置列表里加对应值即可,不需要改动核心处理代码。
优化后的代码如下:

library(dplyr)
library(readr)
library(sf)
library(purrr)

# 根目录配置:所有dataset_*文件夹的上级路径
root_path <- "C:/Users/Downloads/global_data"
# 待处理年份配置:后续新增年份直接往向量里追加即可
target_years <- c(2006, 2007)
# 筛选标签配置,需要调整筛选规则直接改这里
filter_labels <- c("AR45T", "GK879")

# 单年份数据处理通用函数
process_year_data <- function(year, root_dir, filter_tags) {
  # 拼接对应年份的文件夹完整路径,不需要切换工作目录
  year_folder <- file.path(root_dir, paste0("dataset_", year))
  
  # 读取并合并当年所有shp文件
  shp_files <- list.files(year_folder, pattern = paste0('data_', year, '.*\\.shp$'), full.names = TRUE)
  combined_shp <- map_dfr(shp_files, st_read)
  
  # 读取并合并当年所有csv文件
  csv_files <- list.files(year_folder, pattern = paste0('csv_', year, '_.*\\.csv$'), full.names = TRUE)
  csv_combined <- csv_files %>%
    set_names() %>%
    map_dfr(read_delim, delim = ";", .id = "file_name")
  
  # 表关联并按规则筛选
  final_data <- merge(combined_shp, csv_combined, by = "ID") %>%
    filter(label %in% filter_tags)
  
  # 结果导出到对应年份文件夹
  output_path <- file.path(year_folder, paste0("new_shp_", year, ".shp"))
  st_write(final_data, output_path, overwrite = TRUE)
  
  return(invisible(final_data))
}

# 批量遍历所有目标年份执行处理
walk(target_years, ~process_year_data(.x, root_path, filter_labels))

优化说明

  • 移除了setwd切换工作目录的逻辑,全程通过路径拼接定位文件,不会因为工作目录混乱出现文件找不到的报错
  • 重复处理逻辑封装为独立函数,代码冗余度大幅降低
  • 合并shp时直接用map_dfr实现,替代原来lapply + 手动调用sf包内部函数rbind.sf的写法,更稳定,不会因为sf包版本更新出现内部函数变动的问题
  • 所有可变配置(根路径、待处理年份、筛选标签)统一抽离到代码开头,调整参数不需要翻找核心处理逻辑
  • 用walk执行批量导出操作,是purrr包处理带副作用的批量操作的标准写法,执行效率更高

内容的提问来源于stack exchange,提问作者zakros

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 16:12:28