了解raster::extract和terra:extract

9

我不太明白terra:extract的使用。我想要提取行政GADM多边形的平均栅格值。我的栅格每个国家只有一个值。我期望在一个特定国家内的每个行政多边形都具有相同的值,并且包括一些国界线的某些多边形将被分配面积加权平均值。但是,我的当前脚本并非如此。raster::extract似乎给出了合理的结果,但是terra:extract却没有(请参见下面的示例代码 - 提供具有不同值的输出)。能否有人根据下面的代码解释一下原因?非常感谢。

## libraries
library(terra)
library(raster)

#===============================================    
## sample example - provides results as expected (1.333, that is (2*0.5+1*1)/1.5)

# sample raster and SpatialPolygons
r <- raster(ncol=2, nrow=3, xmn= 0, ymn= 0, xmx = 30,ymx = 30)
r[] <- c(2, 2, 2, 1, NA, NA)
cds <- rbind(c(7.5,0), c(7.5,20), c(30, 20),c(30,10))
library(sp)
p = Polygon(cds)
ps = Polygons(list(p),1)
sps = SpatialPolygons(list(ps))
plot(r)
plot(sps, add=T)

enter image description here

# test raster package
test1 <- raster::extract(r , sps, fun=mean, na.rm=T,  weights=TRUE) 
test1 # I get 1.333333 which is what I would expect

# test terra package
sps.spatv <- vect(sps)
r.spatR <-  rast(r) #conversion to SpatRaster class

test2 <- terra::extract(r.spatR, sps.spatv, fun=mean, na.rm=T,  weights=TRUE, exact=TRUE, touches=TRUE) 
test2 # I get 1.333333 which is what I would expect  

#===============================================    
## sample code that leads to different results between raster and terra packages - I wish to understand why such difference.
# sample SpatialPolygonsDataFrame 
ETH <- getData("GADM", country = 'ETH', level = 2)
SOM <- getData("GADM", country = 'SOM', level = 2)
sps <- bind(ETH, SOM)

# sample raster stack
ra <- raster(ncol=31, nrow=24, xmn= 33.3, ymn=  3.67, xmx = 47.5, ymx = 14.65, crs=crs(sps) )
ra[] <- rep(10, 24*31)
ra2 <- raster(ncol=31, nrow=24, xmn= 33.3, ymn= -7.31 , xmx = 47.5, ymx = 3.67, crs=crs(sps) )
ra2[] <- rep(20, 24*31)
ra3 <- merge(ra, ra2)

rb <- raster(ncol=31, nrow=24, xmn= 33.3, ymn=  3.67, xmx = 47.5, ymx = 14.65, crs=crs(sps) )
rb[] <- rep(35, 24*31)
rb2 <- raster(ncol=31, nrow=24, xmn= 33.3, ymn= -7.31 , xmx = 47.5, ymx = 3.67, crs=crs(sps) )
rb2[] <- rep(45, 24*31)
rb3 <- merge(rb, rb2)

stack.r <- stack(ra3, rb3)
names(stack.r) <- c("ra3", "rb3")

plot(stack.r[[1]])
plot(sps, add=T)

# raster::extract
rastR <- raster::extract(stack.r, sps, fun=mean, na.rm=T,  weights=TRUE)

# > head(rastR)
# [,1] [,2]
# [1,]   10   35
# [2,]   10   35
# [3,]   10   35
# [4,]   10   35
# [5,]   10   35
# [6,]   10   35

rastR2 <- rastR %>%
  cbind(sps@data["GID_2"]) # add ID

# terra::extract
sps.spatv <- vect(sps)
stack.r.spatR <-  rast(stack.r) 
rastT <- terra::extract(stack.r.spatR, sps.spatv, fun=mean, na.rm=T,  exact=TRUE)
# > head(rastT)
# ID ra3 rb3
# [1,]  1  10  10
# [2,]  2  10  10
# [3,]  3  10  10
# [4,]  4  10  10
# [5,]  5  10  10
# [6,]  6  10  10
rastT2 <- rastT %>%
  cbind(sps@data["GID_2"]) # add ID
1个回答

11
感谢您提供更详细的问题描述,并坚持不懈地追问。在terra中存在一个错误,现已得到修复:
以下是您提供的简化示例数据:
library(raster)
library(terra)
#terra version 1.7.29

sp <- getData("GADM", country = 'ETH', level = 2)[1:3,]
sv <- vect(sp)

ra <- raster(ncols=31, nrows=24, xmn= 33.3, ymn=  3.67, xmx = 47.5, ymx = 14.65, crs=crs(sp), vals=rep(10, 24*31))
rb <- raster(ncols=31, nrows=24, xmn= 33.3, ymn=  3.67, xmx = 47.5, ymx = 14.65, crs=crs(sv), vals=rep(35, 24*31))

r_raster <- stack(ra, rb)
names(r_raster) <- c("ra", "rb")
r_terra <-  rast(r_raster) 

测试 不使用权重small=FALSE 用于 raster

extract(r_raster, sp, fun=mean, na.rm=T, small=FALSE)
#     [,1] [,2]
#[1,]   NA   NA
#[2,]   10   35
#[3,]   10   35

extract(r_terra, sv, fun=mean, na.rm=T)
#  ID  ra  rb
#1  1  10  35
#2  2  10  35
#3  3  10  35

请注意,`terra` 也会返回一个不包含任何单元格中心的多边形的值。为了避免返回 NA,实际上对于这样的多边形,始终使用选项 `touches=TRUE`。
测试时,请使用无权重small=TRUE 来进行raster(默认)操作。
extract(r_raster, sp, fun=mean, na.rm=T)
#      ra rb
#[1,] 10 35
#[2,] 10 35
#[3,] 10 35

extract(r_terra, sv, fun=mean, na.rm=T, touches=TRUE)
#  ID ra rb
#1  1 10 35
#2  2 10 35
#3  3 10 35
 

测试带权重

extract(r_raster, sp, fun=mean, na.rm=T,  weights=TRUE)
#     ra rb
#[1,] 10 35
#[2,] 10 35
#[3,] 10 35

extract(r_terra, sv, fun=mean, na.rm=T,  weights=TRUE)
#     ID ra rb
#[1,]  1 10 35
#[2,]  2 10 35
#[3,]  3 10 35

1
非常感谢,我已经在我的问题中添加了更多细节。你的例子对我来说很有意义。你的结果是我所期望的。我真的很想知道为什么我的两个输出tibbles Nadmin2R和Nadmin2T提供如此不同的结果。Nadmin2R似乎是正确的,但Nadmin2T包含我无法解释的值...我可能误解了什么。 - Cecile
2
你能否简化代码,只显示埃塞俄比亚某些地区的两个提取物的输出?其他所有代码让人难以理解正在发生什么。或者更好的做法是,从类似eth <- getData("GADM", country="ETH", level=1")的内容开始创建一个可复现的示例。 - Robert Hijmans
1
感谢您的建议。我已经修改了我的问题,包含了一个可重现的示例。 - Cecile
1
亲爱的罗伯特,目前我的理解是我要么没有正确使用terra::extract函数来处理栅格堆栈,要么是terra::extract不能用于栅格堆栈。如果你再次看到这篇文章,我很想听听你的想法。谢谢。 - Cecile
1
感谢您的坚持,并为我花费了很长时间才理解您所报告的内容而道歉。 - Robert Hijmans
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接