terra包extract函数weights与exact参数差异及加权均值疑问
关于terra包extract函数weights与exact参数的区别及加权均值计算问题
问题说明
我需要计算多边形范围内栅格的加权均值,测试terra::extract函数时发现以下现象:
- 设置
weights=T返回的weight值与exact=T返回的fraction值存在明显差异; - 结合
fun=mean和weights=T计算加权均值时得到NaN结果,而exact=T能得到有效结果; - 手动用
fraction计算的加权均值与exact=T的结果完全一致,因此疑惑weights参数的具体用途。
测试代码及结果
基础数据准备
library(terra) # 加载多边形数据 f <- system.file("ex/lux.shp", package="terra") v <- vect(f) v <- v[1:2,] # 加载栅格数据 rf <- system.file("ex/elev.tif", package="terra") x <- rast(rf)
提取结果对比
设置weights=T的提取结果:
head(terra::extract(x, v, weight = T, touches = T))
输出:
ID elevation weight 1 1 NA 0.08 2 1 NA 0.17 3 1 529 0.30 4 1 542 0.52 5 1 547 0.74 6 1 535 0.18
设置exact=T的提取结果:
head(terra::extract(x, v, exact = T, touches = T))
输出:
ID elevation fraction 1 1 NA 0.03471857 2 1 NA 0.11553771 3 1 529 0.23902885 4 1 542 0.45706171 5 1 547 0.68120503 6 1 535 0.12033581
加权均值计算对比
用weights=T计算加权均值:
terra::extract(x, v, fun = mean, weights = T, touches = T, na.rm = T)
输出:
ID elevation 1 1 NaN 2 2 NaN
用exact=T计算加权均值:
terra::extract(x, v, fun = mean, exact = T, touches = T, na.rm = T)
输出:
ID elevation 1 1 467.3792 2 2 334.6856
手动验证
用exact=T返回的fraction手动计算加权均值:
test_df <- terra::extract(x, v, exact = T, touches = T, na.rm = T) test_df %>% dplyr::group_by(ID) %>% dplyr::summarise(wt_mean = weighted.mean(elevation, fraction, na.rm = T))
输出:
ID wt_mean 1 467. 2 335.
参数区别及weights用途解析
核心区别
- exact参数:返回的
fraction是栅格单元格落在多边形内的面积占比,完全基于空间重叠的面积比例,是计算多边形范围内栅格面积加权均值的正确参数。 - weights参数:返回的
weight是基于栅格单元格中心到多边形边界的距离计算的权重,距离越近权重越高,距离越远权重越低。它不是用来计算面积占比的,而是用于距离衰减类的空间分析。
为什么weights=T会得到NaN
设置touches=T时,会包含那些单元格中心在多边形外但与多边形边界接触的栅格,这些栅格的elevation为NA,但weight有值。当用fun=mean结合weights=T时,即使设置na.rm=T,函数内部仍会将带权重的NA纳入计算逻辑,最终导致结果为NaN;而exact=T的内部处理逻辑会正确忽略带NA值的行,仅用有效栅格值和对应面积占比计算加权均值。
weights参数的适用场景
适合需要考虑空间距离衰减效应的分析,例如:
- 计算城市边界周边区域的平均噪音值,距离边界越近权重越高;
- 分析保护区周边植被受人类活动影响的程度,距离保护区越远权重越低。
内容的提问来源于stack exchange,提问作者89_Simple
相关产品推荐
相关产品推荐

