批量处理NetCDF火险气象数据:旋转裁剪、CRS更新及循环报错解决
问题分析与修复方案
报错原因
你遇到的Error in if (filename == "") { : the condition has length > 1,核心原因是writeRaster中使用了names(r)作为文件名后缀——names(r)是对应365/366个图层的名字向量,会生成多个文件名,而默认writeRaster不支持同时将一个多图层对象输出到多个独立文件路径,触发了内部条件判断的长度错误。
同时你的代码还存在几个隐性问题:
projectRaster执行后未赋值给变量,等于没有执行投影操作- 混用
raster和terra包的裁剪函数,易引发跨包兼容问题 - 最终写入的是未处理的原对象
r,而非处理后的r2
修复后的代码(基于raster包)
library(raster) # 获取所有NetCDF文件路径,注意正则转义. all_nc <- list.files("C:/file_path/", pattern = "\\.nc$", recursive = FALSE, full.names = TRUE) # 定义研究区范围(统一用raster包的extent) study_ext <- extent(-141.0069, -123.7893, 60, 69.64794) # 循环处理每个文件 for (i in seq_along(all_nc)) { # 读取多图层NetCDF为RasterStack r <- stack(all_nc[i]) # 旋转数据 r_rotated <- raster::rotate(r) # 强制设置CRS(原数据已识别为WGS84,无需重复投影,直接赋值更高效) crs(r_rotated) <- "+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0" # 裁剪至研究区 r_cropped <- crop(r_rotated, study_ext) # 生成输出文件名(保留原文件名,仅替换路径) out_filename <- file.path("D:/path/", basename(all_nc[i])) # 写入处理后的NetCDF,保持原365/366层结构 writeRaster(r_cropped, filename = out_filename, force_v4 = TRUE, overwrite = TRUE, format = "CDF", compression = 7) # 清理内存(处理大量文件时建议添加) rm(r, r_rotated, r_cropped) gc() }
可选:基于terra包的优化版本(raster包的替代方案)
由于raster包已进入维护阶段,推荐使用terra包处理空间数据:
library(terra) all_nc <- list.files("C:/file_path/", pattern = "\\.nc$", recursive = FALSE, full.names = TRUE) study_ext <- ext(-141.0069, -123.7893, 60, 69.64794) target_crs <- "+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0" for (i in seq_along(all_nc)) { # 读取为SpatRaster r <- rast(all_nc[i]) # 旋转数据 r_rotated <- rotate(r) # 设置CRS crs(r_rotated) <- target_crs # 裁剪至研究区 r_cropped <- crop(r_rotated, study_ext) # 生成输出文件名 out_filename <- file.path("D:/path/", basename(all_nc[i])) # 写入NetCDF文件 writeCDF(r_cropped, filename = out_filename, force_v4 = TRUE, overwrite = TRUE, compression = 7) }
内容的提问来源于stack exchange,提问作者user11384727
相关产品推荐
相关产品推荐

