如何在R中对.tif文件应用相似性模型,匹配加州与西班牙气候相似坐标?
用R实现气候点位匹配方案
以下方案基于terra(栅格处理)和tidyverse(数据处理)工具链,完美适配你的需求:
1. 读取并合并西班牙的气候TIFF
先把所有气候变量的TIFF文件读入,合并成一个多波段栅格对象,方便后续处理:
library(terra) library(tidyverse) # 替换成你的TIFF文件路径 spain_tmax <- rast("spain_tmax.tif") spain_tmin <- rast("spain_tmin.tif") spain_tavg <- rast("spain_tavg.tif") spain_precip <- rast("spain_precip.tif") # 合并为多波段栅格,给波段命名(要和你的加州数据框列名对应) spain_clim <- c(spain_tmax, spain_tmin, spain_tavg, spain_precip) names(spain_clim) <- c("tmax", "tmin", "tavg", "precip")
2. 把西班牙栅格转成数据框
提取所有有效栅格点的坐标和气候值(自动过滤NA值,比如海洋区域):
# xy=TRUE 保留经度(x)、纬度(y)列,na.rm=TRUE 去掉无数据的点 spain_df <- as.data.frame(spain_clim, xy = TRUE, na.rm = TRUE)
3. 标准化变量(必做!)
温度和降水量的量纲差很大,直接算距离会被降水量主导,所以先做z-score标准化:
# 标准化西班牙的气候变量 spain_df[, c("tmax", "tmin", "tavg", "precip")] <- scale(spain_df[, c("tmax", "tmin", "tavg", "precip")]) # 同样标准化你的加州数据框(假设叫california_df,列包含x,y,tmax,tmin,tavg,precip) california_df[, c("tmax", "tmin", "tavg", "precip")] <- scale(california_df[, c("tmax", "tmin", "tavg", "precip")])
4. 匹配每个加州点的最相似西班牙点
定义一个函数,对单个加州点计算和所有西班牙点的欧氏距离(距离越小越相似),然后返回距离最小的点:
# 定义匹配函数 find_most_similar <- function(cal_point, spain_df) { # 提取当前加州点的标准化气候值 cal_vars <- cal_point %>% select(tmax, tmin, tavg, precip) %>% unlist() # 计算每个西班牙点与当前加州点的欧氏距离 spain_df <- spain_df %>% mutate(distance = sqrt((tmax - cal_vars["tmax"])^2 + (tmin - cal_vars["tmin"])^2 + (tavg - cal_vars["tavg"])^2 + (precip - cal_vars["precip"])^2)) # 取距离最小的那个西班牙点 top_match <- spain_df %>% slice_min(distance, n = 1) %>% select(x, y, distance) # 把加州点坐标和匹配结果合并 result <- cal_point %>% select(x, y) %>% rename(cal_x = x, cal_y = y) %>% bind_cols(top_match %>% rename(spain_x = x, spain_y = y)) return(result) } # 对加州的16个点批量匹配 matched_results <- purrr::map_dfr(california_df, find_most_similar, spain_df = spain_df)
5. 结果说明
matched_results数据框里会有:
cal_x/cal_y:加州点位的经纬度spain_x/spain_y:对应的西班牙最相似气候点位的经纬度distance:两者的标准化气候变量欧氏距离(值越小,相似度越高)
可选优化
- 如果西班牙TIFF分辨率太高,计算慢:可以先聚合降分辨率,减少计算量
# 把栅格分辨率降低为原来的1/2(fact=2,可根据需求调整) spain_clim_agg <- aggregate(spain_clim, fact = 2, fun = mean) spain_df_agg <- as.data.frame(spain_clim_agg, xy = TRUE, na.rm = TRUE)
- 想用相关系数衡量相似度(看变量趋势一致性):修改函数里的计算逻辑
find_most_similar_cor <- function(cal_point, spain_df) { cal_vars <- cal_point %>% select(tmax, tmin, tavg, precip) %>% unlist() spain_df <- spain_df %>% mutate(correlation = cor(cbind(cal_vars, c(tmax, tmin, tavg, precip)))[1,2]) top_match <- spain_df %>% slice_max(correlation, n = 1) %>% select(x, y, correlation) result <- cal_point %>% select(x, y) %>% rename(cal_x = x, cal_y = y) %>% bind_cols(top_match %>% rename(spain_x = x, spain_y = y)) return(result) }
内容的提问来源于stack exchange,提问作者Raúl
相关产品推荐
相关产品推荐

