You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 03:42:41