在R中基于ERA5逐小时NetCDF数据计算月均最高气温的方法咨询
解决方案
完全可以通过ncdf4、raster包实现需求,更推荐使用新一代空间数据处理包terra,它的延迟读取、维度聚合效率远高于传统的全量加载转换思路,不需要把41年逐小时数据全部读入内存即可完成计算,完美解决大文件处理的报错问题。
核心思路
- 不需要把NC文件全量转换为csv,通过
terra的延迟读取机制,只在计算时读取必要的数据块 - 提取NC文件的时间维度,识别每个时次对应的年、月分组
- 按年月分组对所有网格的逐小时最高温做聚合计算,得到逐月平均
- 分别输出栅格格式的网格结果、整理后的表格型时间序列
实现代码
1. 加载依赖包
# 安装依赖(首次使用执行) install.packages(c("terra", "lubridate", "dplyr", "tidyr")) # 加载包 library(terra) library(lubridate) library(dplyr) library(tidyr)
2. 读取NC文件并解析时间维度
# 读取你下载的NC文件,rast默认延迟读取,不会占用大量内存 nc_rast <- rast("era5-wap-Tmax2m_1979_2019.nc") # 提取时间维度信息并解析为时间格式 nc_time <- time(nc_rast) # 提取每个时次对应的年月标签,作为分组依据 year_month <- paste(year(nc_time), sprintf("%02d", month(nc_time)), sep = "_") # 可选:温度单位从开尔文转换为摄氏度 nc_rast <- nc_rast - 273.15
3. 计算逐月平均最高温
# 按年月分组聚合,fun指定计算平均值,na.rm处理缺测值 monthly_mean_tmax <- tapp(nc_rast, index = year_month, fun = mean, na.rm = TRUE) # 给输出的栅格层设置时间标签 time(monthly_mean_tmax) <- ymd(paste0(unique(year_month), "_01"))
4. 输出网格结果
# 输出为NetCDF格式网格文件,保留空间坐标和时间信息 writeRaster(monthly_mean_tmax, "逐月平均最高温_网格结果.nc", overwrite = TRUE) # 也可输出为tif格式,每层对应一个月 writeRaster(monthly_mean_tmax, "逐月平均最高温_网格结果.tif", overwrite = TRUE)
5. 输出表格型时间序列
# 栅格转数据框,保留经纬度信息 tmax_df <- as.data.frame(monthly_mean_tmax, xy = TRUE) # 转换为长格式:列名对应 经度、纬度、年月、平均最高温 tmax_long <- tmax_df %>% pivot_longer(cols = -c(x, y), names_to = "year_month", values_to = "mean_tmax") # 输出为csv文件 write.csv(tmax_long, "逐月平均最高温_时间序列.csv", row.names = FALSE, na = "")
注意事项
- 如果你的设备内存极小,可以按年份拆分计算:每次读取1年的NC数据,计算当年的逐月平均后再读取下一年,最后合并结果即可
- 输出的表格如果需要宽格式(每个网格对应一列,每行对应一个月),可以在长格式的基础上用
pivot_wider转换即可 - 你从CDS申请数据的参数完全正确,不需要调整下载配置
内容的提问来源于stack exchange,提问作者Patricia
相关产品推荐
相关产品推荐

