单个多边形的光栅标准化

发布于 2025-02-11 01:39:40 字数 1245 浏览 1 评论 0原文

library(raster)
library(rnaturalearth)
library(terra)

r <- raster::getData('CMIP5', var='tmin', res=10, rcp=45, model='HE', year=70)
r <- r[[1]]    
shp <- rnaturalearth::ne_countries()

newcrs <- "+proj=robin +datum=WGS84"

r <- rast(r)
shp <- vect(shp)
r_pr <- terra::project(r, newcrs)            
shp_pr <- terra::project(shp, newcrs)            

对于shp_pr中的每个国家/地区,我要标准化基础栅格 以0-1的比例。这意味着将一个牢房除以一个国家边界内的所有单元的总和,并为所有国家重复。我正在这样做如下:

country_vec <- shp$sovereignt

temp_ls <- list()

for(c in seq_along(country_vec)){
  
  country_ref <- country_vec[c]
  
  if(country_ref == "Antarctica") { next }      
  
  shp_ct <- shp[shp$sovereignt == country_ref]

  r_country <- terra::crop(r, shp_ct) # crops to the extent of boundary 
  r_country <- terra::extract(r_country, shp_ct, xy=T) 
  r_country$score_norm <- r_country$he45tn701/sum(na.omit(r_country$he45tn701))
  r_country_norm_rast <- rasterFromXYZ(r_country[ , c("x","y","score_norm")])
  
  temp_ls[[c]] <- r_country_norm_rast
  
  rm(shp_ct, r_country, r_country_norm_rast)
  }    

m <- do.call(merge, temp_ls)

我想知道这是否是执行此操作的最有效/正确的方法,即没有任何循环,任何人都有任何建议?

library(raster)
library(rnaturalearth)
library(terra)

r <- raster::getData('CMIP5', var='tmin', res=10, rcp=45, model='HE', year=70)
r <- r[[1]]    
shp <- rnaturalearth::ne_countries()

newcrs <- "+proj=robin +datum=WGS84"

r <- rast(r)
shp <- vect(shp)
r_pr <- terra::project(r, newcrs)            
shp_pr <- terra::project(shp, newcrs)            

For every country in shp_pr, I want to normalise the underlying raster
on a scale of 0-1. This means dividing a cell by the sum of all the cells within a country boundary and repeating it for all the countries. I am doing this as follows:

country_vec <- shp$sovereignt

temp_ls <- list()

for(c in seq_along(country_vec)){
  
  country_ref <- country_vec[c]
  
  if(country_ref == "Antarctica") { next }      
  
  shp_ct <- shp[shp$sovereignt == country_ref]

  r_country <- terra::crop(r, shp_ct) # crops to the extent of boundary 
  r_country <- terra::extract(r_country, shp_ct, xy=T) 
  r_country$score_norm <- r_country$he45tn701/sum(na.omit(r_country$he45tn701))
  r_country_norm_rast <- rasterFromXYZ(r_country[ , c("x","y","score_norm")])
  
  temp_ls[[c]] <- r_country_norm_rast
  
  rm(shp_ct, r_country, r_country_norm_rast)
  }    

m <- do.call(merge, temp_ls)

I wondered if this is the most efficient/right way to do this i.e. without any for loop and anyone has any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

诗化ㄋ丶相逢 2025-02-18 01:39:40

有些更新且简化的示例数据(不需要投影数据)

library(terra)
library(geodata)
r <- geodata::cmip6_world("HadGEM3-GC31-LL", "585", "2061-2080", "tmin", 10, ".")[[1]]
v <- world(path=".")
v$ID <- 1:nrow(v)

解决方案

z <- rasterize(v, r, "ID", touches=TRUE)    
zmin <- zonal(r, z, min, na.rm=TRUE, as.raster=TRUE)
zmax <- zonal(r, z, max, na.rm=TRUE, as.raster=TRUE)
x <- (r - zmin) / (zmax - zmin)

每个国家 /地区的单元格值归一化为0到1。

请注意,以上的数据将 您可以做:

z <- rasterize(v, r, "ID", touches=TRUE)    
zsum <- zonal(r, z, sum, na.rm=TRUE, as.raster=TRUE)
x <- r / zsum

Somewhat updated and simplified example data (there is no need for projection the data)

library(terra)
library(geodata)
r <- geodata::cmip6_world("HadGEM3-GC31-LL", "585", "2061-2080", "tmin", 10, ".")[[1]]
v <- world(path=".")
v$ID <- 1:nrow(v)

Solution

z <- rasterize(v, r, "ID", touches=TRUE)    
zmin <- zonal(r, z, min, na.rm=TRUE, as.raster=TRUE)
zmax <- zonal(r, z, max, na.rm=TRUE, as.raster=TRUE)
x <- (r - zmin) / (zmax - zmin)

Note that the above normalizes the cell values for each country between 0 and 1.

To transform the data such that the values add up to 1 (by country), you can do:

z <- rasterize(v, r, "ID", touches=TRUE)    
zsum <- zonal(r, z, sum, na.rm=TRUE, as.raster=TRUE)
x <- r / zsum
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文