在R中使用terra关联焦点像元ID与皇后邻域像元ID
栅格焦点像元与皇后邻域像元ID的高效关联方法
我有一个大型栅格数据,需要将每个**焦点像元(focal cell)的ID与其皇后邻域(queen neighbours)**的像元ID关联(需包含焦点像元自身)。每个焦点像元是代表动物利用区域的5km方格,邻域像元为该位置的可选区域(焦点像元本身也属于可选区域),后续要在这些5km方格内提取30m分辨率的协变量。
我试过Stack Overflow上的方案,但生成不了我需要的一对多格式数据。
示例栅格生成代码
library(terra) # 创建5x5的测试栅格 d = rast(nrow = 5, ncol = 5) # 为每个像元分配唯一ID values(d) <- 1:ncell(d) # 选取几个测试用的焦点像元ID cell_ids = c(3, 14, 22) # 不确定这行是否必要,暂时保留 dvec = as.data.frame(d) colnames(dvec) = "focal_id"
尝试用terra::adjacent但未得到正确结果
一开始直接调用terra::adjacent后手动拼接ID,结果格式不对:
# 获取邻域像元ID,但直接转成向量后丢失了对应关系 dadj = as.vector(terra::adjacent(d, cells = cell_ids, include = TRUE, directions = "queen")) # 手动重复焦点像元ID,每个对应9个邻域像元 cell.rep = rep(c(3,14,22),each=9) # 这样组合出来的结果不符合预期 df = as.data.frame(cbind(cell.rep, dadj))
可行但效率低的循环实现
后来写出了能生成正确格式的循环代码,但面对大型栅格时效率太差,想找更高效的实现方式:
# 手动重复焦点像元ID cell.rep = rep(c(3,14,22),each=9) dadj = c() for(i in cell_ids){ # 逐个获取每个焦点像元的邻域ID并拼接 adel = as.vector(terra::adjacent(d, cells = i, include = TRUE, directions = "queen")) dadj = c(dadj, adel) } # 组合成一对多的DataFrame df = as.data.frame(cbind(cell.rep, dadj))
高效实现方法
其实terra::adjacent本身就会返回焦点像元与邻域像元的对应矩阵,不需要手动循环或重复ID,直接处理这个矩阵即可:
library(terra) d = rast(nrow = 5, ncol = 5) values(d) <- 1:ncell(d) cell_ids = c(3, 14, 22) # 调用adjacent,返回的矩阵第一列是焦点像元ID,第二列是对应邻域像元ID adj_matrix = terra::adjacent(d, cells = cell_ids, include = TRUE, directions = "queen") # 转成DataFrame并重命名列,得到标准的一对多格式 df = as.data.frame(adj_matrix) colnames(df) = c("focal_id", "neighbour_id")
这个方法完全利用terra包的原生函数输出,避免了循环和手动拼接,处理大型栅格数据时效率会大幅提升。
内容的提问来源于stack exchange,提问作者rgill
相关产品推荐
相关产品推荐

