请使用terra 和sf 库找到一种可能的解决方案。
这个想法是将SpatRaster r 转换为SpatVector,然后转换为sf 对象,以便使用sf::st_join() 函数使用largest = TRUE 参数。剩下的代码包括简单地将sf 对象转换回SpatVector,然后使用terra::rasterize() 函数转换为SpatRaster。
所以,请在下面找到详细说明该过程的代表。
Reprex
library(terra)
library(sf)
# Your data
f <- system.file("ex/lux.shp", package="terra")
v <- vect(f)
r <- rast(v, ncols = 3, nrow = 3)
rcc <- vect(xyFromCell(r, cell = 1:ncell(r)))
# Convert the 'SpatRaster' 'r' into a 'SpatVector (i.e. 'r_poly')
r_poly <- terra::as.polygons(r)
# Convert 'r_poly' into a 'sf' object (i.e. 'r_poly_sf')
r_poly_sf <- sf::st_as_sf(r_poly)
# Convert 'v' into a 'sf' object (i.e. 'v_sf')
v_sf <- sf::st_as_sf(v)
# Left join r_poly_sf with v_sf based on the largest overlap
results_sf <- sf::st_join(r_poly_sf, v_sf, largest = TRUE)
# Convert 'results_sf' into a SpatVector (i.e. 'results_vect')
results_vect <- terra::vect(results_sf)
# Rasterize 'results_vect' to get a 'SpatRaster' (i.e. 'results')
results <- terra::rasterize(results_vect, r, field = "NAME_2")
results
#> class : SpatRaster
#> dimensions : 3, 3, 1 (nrow, ncol, nlyr)
#> resolution : 0.2613707, 0.2446047 (x, y)
#> extent : 5.74414, 6.528252, 49.44781, 50.18162 (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 (EPSG:4326)
#> source : memory
#> name : NAME_2
#> min value : Capellen
#> max value : Remich
terra::values(results, dataframe=TRUE)
#> NAME_2
#> 1 Clervaux
#> 2 Clervaux
#> 3 <NA>
#> 4 Redange
#> 5 Mersch
#> 6 Echternach
#> 7 Capellen
#> 8 Luxembourg
#> 9 Remich
plot(results)
lines(r, col = "light gray")
lines(v)
points(rcc)
由reprex package 创建于 2022-02-10 (v2.0.1)
与上面完全相同,但使用rast(v, ncols = 5, nrow =5) 可以获得可以与您在问题中提供的数字进行比较的结果。
library(terra)
library(sf)
# Your data
f <- system.file("ex/lux.shp", package="terra")
v <- vect(f)
r <- rast(v, ncols = 5, nrow = 5)
rcc <- vect(xyFromCell(r, cell = 1:ncell(r)))
# Convert the 'SpatRaster' 'r' into a 'SpatVector (i.e. 'r_poly')
r_poly <- terra::as.polygons(r)
# Convert 'r_poly' into a 'sf' object (i.e. 'r_poly_sf')
r_poly_sf <- sf::st_as_sf(r_poly)
# Convert 'v' into a 'sf' object (i.e. 'v_sf')
v_sf <- sf::st_as_sf(v)
# Left join r_poly_sf with v_sf based on the largest overlap
results_sf <- sf::st_join(r_poly_sf, v_sf, largest = TRUE)
#> Warning: attribute variables are assumed to be spatially constant throughout all
#> geometries
# Convert 'results_sf' into a SpatVector (i.e. 'results_vect')
results_vect <- terra::vect(results_sf)
# Rasterize 'results_vect' to get a 'SpatRaster' (i.e. 'results')
results <- terra::rasterize(results_vect, r, field = "NAME_2")
results
#> class : SpatRaster
#> dimensions : 5, 5, 1 (nrow, ncol, nlyr)
#> resolution : 0.1568224, 0.1467628 (x, y)
#> extent : 5.74414, 6.528252, 49.44781, 50.18162 (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 (EPSG:4326)
#> source : memory
#> name : NAME_2
#> min value : Capellen
#> max value : Wiltz
terra::values(results, dataframe=TRUE)
#> NAME_2
#> 1 Clervaux
#> 2 Clervaux
#> 3 Clervaux
#> 4 <NA>
#> 5 <NA>
#> 6 Wiltz
#> 7 Wiltz
#> 8 Vianden
#> 9 Vianden
#> 10 <NA>
#> 11 Redange
#> 12 Redange
#> 13 Mersch
#> 14 Echternach
#> 15 Echternach
#> 16 Capellen
#> 17 Capellen
#> 18 Luxembourg
#> 19 Grevenmacher
#> 20 Grevenmacher
#> 21 Esch-sur-Alzette
#> 22 Esch-sur-Alzette
#> 23 Esch-sur-Alzette
#> 24 Remich
#> 25 Remich
plot(results)
lines(r, col = "light gray")
lines(v)
points(rcc)
由reprex package (v2.0.1) 于 2022-02-10 创建