如何用terra包复刻raster农药施用栅格统计,解决mask函数报错问题
报错根源
terra和raster的area()函数行为完全不一致,这是你遇到类型错误的核心原因:
raster::area(r)会返回与输入栅格同分辨率、同范围的栅格对象,每个像元值对应该像元的实际面积(单位平方公里)- 而
terra::area(r)默认计算的是整个栅格覆盖范围的总表面积,返回值为单个数值(也就是报错提示中的numeric类型),将这个数值传入mask()时,不存在匹配的方法可处理,因此抛出类型不匹配错误。
修正方案
将逐像元面积计算的代码替换为terra中专门生成逐像元面积栅格的cellSize()函数即可,其余处理逻辑完全不需要改动:
- 原错误代码:
a <- terra::area(r) * 100 - 替换为:
a <- terra::cellSize(r) * 100cellSize()返回与r结构完全一致的SpatRaster对象,每个像元值为对应像元的面积(单位为平方公里,与raster::area的输出单位完全匹配,后续乘100转换为公顷的逻辑无需调整)。
修正后的完整可运行代码
## Terra ---- library(terra) library(sp) # 加载wrld_simpl示例数据需要依赖 data(wrld_simpl) wrld_simpl = vect(wrld_simpl) r <- terra::rast("https://raw.github.com/hansronald/Pesticide-data/master/APR_Soybean_Glyphosate_2015_L.tif") r <- terra::clamp(r, lower=0, values=FALSE) # 逐像元面积(单位:公顷) a <- terra::cellSize(r) * 100 ## 各国平均施用率 mean_app <- terra::extract(r, wrld_simpl, fun = mean, na.rm = TRUE) rtot <- r * a ## 各国总施用量 tot_app <- terra::extract(rtot, wrld_simpl, fun = sum, na.rm = TRUE) ## 有效统计面积 rarea <- terra::mask(a, r) tot_area <- terra::extract(rarea, wrld_simpl, fun = sum, na.rm = TRUE)
适配原raster代码的小调整
如果需要让提取结果的结构与原raster代码完全对齐,可给所有terra::extract()调用增加bind = TRUE参数,返回的结果会直接拼接在wrld_simpl的属性表上,与原raster输出的使用逻辑一致,示例:mean_app <- terra::extract(r, wrld_simpl, fun = mean, na.rm = TRUE, bind = TRUE)
内容的提问来源于stack exchange,提问作者Robin Lindström
相关产品推荐
相关产品推荐

