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

如何在R中批量处理多个.bil文件并自动命名输出文件

问题

需要对400个不同的.bil数据集执行数据转换操作,已掌握单个文件的处理方法,但自动化处理时遇到问题——无法自动从原.bil文件名提取编号来命名输出的Shapefile和CSV文件。

单个.bil文件处理代码

library(cruts)
library(raster)
library(sf)
library(rgdal)
library(terra)
require(rgdal)

rdata <- "G:/Mon Drive/Doctorat/Données/Donnée spatiale indonésie/CHIRPS brut/chirps-v2.0_201410/chirps-v2.0_201410.bil"
sdata <- readOGR("G:/Mon Drive/Doctorat/Données/Donnée spatiale indonésie","sub_pro_indon")

r <- raster(rdata)
r.vals <- extract(r, sdata)
r.mean <- unlist(lapply(r.vals, FUN=mean))
sdata@data <- data.frame(sdata@data, mean=r.mean)

# Write results
writeOGR(sdata,"G:/Mon Drive/Doctorat/Données/Donnée spatiale indonésie/mean.shp", "mean", driver="ESRI Shapefile") 
write.csv2(sdata, "G:/Mon Drive/Doctorat/Données/Donnée spatiale indonésie/mean.csv")

尝试的自动化代码(存在问题)

wd <- "G:/Mon Drive/Doctorat/Données/Donnée spatiale indonésie/CHIRPS brut"
setwd(wd)
files <- list.files(pattern = ".bil")


mean_calc <- function(X){
  r <- raster(rdata)
  r.vals <- extract(r, sdata)
  r.mean <- unlist(lapply(r.vals, FUN=mean))
  sdata@data <- data.frame(sdata@data, mean=r.mean)
  
  writeOGR(sdata,"G:/Mon Drive/Doctorat/Données/Donnée spatiale indonésie/CHIRPS moyenne/201410pre_mean.shp", "201410pre_mean", driver="ESRI Shapefile") 
  write.csv2(sdata, "G:/Mon Drive/Doctorat/Données/Donnée spatiale indonésie/CHIRPS moyenne/201410pre_mean.csv")
  
}


sdata <- readOGR("G:/Mon Drive/Doctorat/Données/Donnée spatiale indonésie","sub_pro_indon")

rdata <- "G:/Mon Drive/Doctorat/Données/Donnée spatiale indonésie/CHIRPS brut/chirps-v2.0_201410.bil"
lapply(rdata, mean_calc)

解决方案

核心改进点

  1. 正确遍历所有.bil文件:原代码仅处理单个文件,需改为遍历files列表并将每个文件名传入函数。
  2. 自动提取文件名编号:用字符串处理工具从.bil文件名中提取目标编号,用于生成输出文件名。
  3. 避免全局数据污染:每次处理时复制sdata副本,防止多次处理后数据叠加。

完整修正代码

library(cruts)
library(raster)
library(sf)
library(rgdal)
library(terra)

# 定义固定路径
input_dir <- "G:/Mon Drive/Doctorat/Données/Donnée spatiale indonésie/CHIRPS brut"
output_dir <- "G:/Mon Drive/Doctorat/Données/Donnée spatiale indonésie/CHIRPS moyenne"
shapefile_path <- "G:/Mon Drive/Doctorat/Données/Donnée spatiale indonésie/sub_pro_indon"

# 创建输出目录(不存在则自动生成)
if (!dir.exists(output_dir)) {
  dir.create(output_dir, recursive = TRUE)
}

# 仅读取一次矢量数据,提升效率
sdata <- readOGR(shapefile_path, "sub_pro_indon")

# 获取所有.bil文件(带完整路径)
files <- list.files(input_dir, pattern = "\\.bil$", full.names = TRUE)

# 定义自动化处理函数
mean_calc <- function(file_path) {
  # 从文件名提取编号(适配chirps-v2.0_201410.bil格式)
  file_name <- basename(file_path)
  file_id <- gsub("^chirps-v2\\.0_(\\d+)\\.bil$", "\\1", file_name)
  output_prefix <- paste0(file_id, "pre_mean")
  
  # 读取栅格数据
  r <- raster(file_path)
  
  # 复制矢量数据副本,避免修改原数据
  sdata_copy <- sdata
  r.vals <- extract(r, sdata_copy)
  # 处理NA值,确保均值计算有效
  r.mean <- unlist(lapply(r.vals, FUN = function(x) mean(x, na.rm = TRUE)))
  sdata_copy@data <- data.frame(sdata_copy@data, mean = r.mean)
  
  # 构建输出文件路径
  shp_output <- file.path(output_dir, paste0(output_prefix, ".shp"))
  csv_output <- file.path(output_dir, paste0(output_prefix, ".csv"))
  
  # 写入结果
  writeOGR(sdata_copy, output_dir, output_prefix, driver = "ESRI Shapefile")
  write.csv2(sdata_copy, csv_output, row.names = FALSE)
  
  # 打印处理进度(可选)
  cat(paste("处理完成:", file_name, "\n"))
}

# 批量处理所有.bil文件
lapply(files, mean_calc)

关键细节说明

  • 正则表达式适配:如果.bil文件名格式变化,需调整gsub中的正则表达式。例如文件名是chirps_201410_v2.bil,正则要改为^chirps_(\\d+)_v2\\.bil$。
  • 路径兼容性:用file.path构建路径,自动适配不同操作系统的路径分隔符,避免手动拼接出错。
  • NA值处理:添加na.rm=TRUE防止栅格中存在NA导致均值计算失败。
  • 效率优化:矢量数据仅读取一次,每次处理用副本,减少重复IO操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 14:19:52