如何将1°分辨率经纬度网格的sw_radiation数据插值至0.5°分辨率?
解决方案
这里提供两种在R中实现规则网格插值降尺度(从1°分辨率提升至0.5°)的可靠方法,均严格限定在原始经纬度范围内插值,不会扩展边界:
方法一:使用raster包(推荐,栅格处理更直观)
raster包专为栅格数据设计,重采样功能可快速实现分辨率提升,默认遵循原始数据范围。
代码实现:
# 加载依赖包 library(raster) # 原始数据初始化 longitude <- seq(from = 60, to = 80, by = 1) latitude <- seq(from = -60, to = -50, by = 1) set.seed(123) # 固定随机种子,方便结果复现 sw_radiation <- matrix(runif(21*11, min = 800, max = 850), nrow = 21, ncol = 11) # 将原始矩阵转为栅格对象(注意转置,raster默认行对应纬度、列对应经度) original_raster <- raster(t(sw_radiation), xmn = min(longitude), xmx = max(longitude), ymn = min(latitude), ymx = max(latitude), crs = "+proj=longlat +datum=WGS84") # 创建目标分辨率的栅格模板(0.5°) target_raster <- raster(xmn = min(longitude), xmx = max(longitude), ymn = min(latitude), ymx = max(latitude), res = 0.5, crs = "+proj=longlat +datum=WGS84") # 执行重采样(双线性插值适合连续数值型数据,也可选用"ngb"最近邻插值) interpolated_raster <- resample(original_raster, target_raster, method = "bilinear") # 转换回矩阵格式(若需要原始矩阵结构) interpolated_matrix <- as.matrix(interpolated_raster) dim(interpolated_matrix) # 输出为41×21,符合目标规模
方法二:使用fields包的interp.surface
fields包的interp.surface针对规则网格插值优化,需先构建原始网格对象,再定义目标坐标网格。
代码实现:
# 加载依赖包 library(fields) # 原始数据初始化(同前) longitude <- seq(from = 60, to = 80, by = 1) latitude <- seq(from = -60, to = -50, by = 1) set.seed(123) sw_radiation <- matrix(runif(21*11, min = 800, max = 850), nrow = 21, ncol = 11) # 构建原始网格对象 original_grid <- list(x = longitude, y = latitude, z = sw_radiation) # 生成目标经纬度网格 target_lon <- seq(from = 60, to = 80, by = 0.5) target_lat <- seq(from = -60, to = -50, by = 0.5) target_coords <- expand.grid(x = target_lon, y = target_lat) # 执行插值 interpolated_values <- interp.surface(original_grid, target_coords) # 转换为目标矩阵格式 interpolated_matrix <- matrix(interpolated_values, nrow = length(target_lon), ncol = length(target_lat)) dim(interpolated_matrix) # 输出为41×21
补充:修复akima::interp的使用问题
如果之前用akima::interp失败,大概率是输入格式问题——该函数需要长格式的坐标-值对,而非矩阵。调整后代码如下:
library(akima) # 将原始矩阵转为长格式数据框 long_df <- expand.grid(lon = longitude, lat = latitude) long_df$sw_radiation <- as.vector(sw_radiation) # 执行插值 akima_result <- interp(x = long_df$lon, y = long_df$lat, z = long_df$sw_radiation, xo = target_lon, yo = target_lat, linear = TRUE) # 提取插值后的矩阵 interpolated_matrix <- akima_result$z
内容的提问来源于stack exchange,提问作者calum.knight
相关产品推荐
相关产品推荐

