R语言读取不同文件夹下同名ASCII文件并计算中位数求助
解决R语言循环仅读取最后一个ASCII文件的问题
问题背景
- 文件夹结构:根目录下为物种命名的文件夹(如
spp1),每个物种文件夹内包含模型文件夹(如model1),每个模型文件夹内有同名ASCII文件(如var1.asc) - 示例文件列表:
$ find path -type f path/spp1/model1/var1.asc path/spp1/model2/var1.asc path/spp2/model1/var1.asc path/spp2/model2/var1.asc
- 需求:针对每个物种,读取其所有模型文件夹中的ASCII文件,计算这些文件数值的中位数并保存结果
现有代码的错误点
- 循环变量冲突:外层和内层循环都使用
i作为索引,导致循环逻辑混乱,无法正确遍历所有模型文件夹 - 变量覆盖:每次内层循环中,
models和stack被重新赋值,之前的结果被覆盖,最终只保留最后一个模型文件夹的文件 - 物种遍历错误:
names <- substr(data[1], ...)始终只取第一个物种的名称,没有遍历所有物种 - 计算对象错误:
median(models)是对文件路径字符串求中位数,而非栅格数据的数值中位数,完全不符合需求
修正后的代码
library(raster) BASEDIR <- "D:/7_Doctorado/Sceloporus/3_Models/kuenm" # 获取所有物种的CSV文件(匹配.csv后缀,避免误匹配) species_csv <- list.files(file.path(BASEDIR, "1_Joint"), pattern = "\\.csv$", full.names = FALSE) # 遍历每个物种 for (i in seq_along(species_csv)) { # 获取当前物种名称(去掉.csv后缀) spp_name <- substr(species_csv[i], 1, nchar(species_csv[i]) - 4) # 读取该物种的最佳模型列表(直接用完整路径,避免切换工作目录) calib_path <- file.path(BASEDIR, paste0("ResultCalibracion_", spp_name), "best_candidate_models_OR_AICc.csv") cal_res <- read.csv(calib_path) model_folders <- cal_res[, 1] # 收集当前物种所有模型文件夹中的ASCII文件路径 all_model_files <- c() for (j in seq_along(model_folders)) { model_path <- file.path(BASEDIR, paste0("Final_Models_", spp_name), paste0(model_folders[j], "_NE")) # 获取当前模型文件夹中的目标ASCII文件(精确匹配后缀) asc_file <- list.files(model_path, pattern = "M_median\\.asc$", full.names = TRUE) all_model_files <- c(all_model_files, asc_file) } # 创建栅格栈并计算中位数、标准差 if (length(all_model_files) > 0) { model_stack <- raster::stack(all_model_files) median_sp <- raster::calc(model_stack, fun = median) sd_sp <- raster::calc(model_stack, fun = sd) # 保存结果(自动创建输出目录) output_dir <- file.path(BASEDIR, "2_Models") if (!dir.exists(output_dir)) dir.create(output_dir) writeRaster(median_sp, filename = file.path(output_dir, paste0(spp_name, "_median")), format = "ascii") writeRaster(sd_sp, filename = file.path(output_dir, paste0(spp_name, "_sd")), format = "ascii") } else { warning(paste("没有找到物种", spp_name, "的ASCII文件")) } }
关键修改说明
- 分离循环变量:内层循环使用
j作为索引,避免与外层循环的i冲突 - 收集所有文件路径:先把所有目标ASCII文件路径存入
all_model_files列表,再一次性创建栅格栈,彻底解决变量覆盖问题 - 正确遍历物种:用
species_csv[i]获取当前物种的CSV文件,确保遍历所有物种 - 基于栅格数据计算:使用
raster::calc对栅格栈逐像素计算中位数和标准差,符合业务需求 - 避免工作目录切换:全程使用完整路径构建文件位置,减少
setwd带来的潜在路径错误
内容的提问来源于stack exchange,提问作者Kevin López Reyes
相关产品推荐
相关产品推荐

