Problem
I want to rasterize polygon values and assign their weighted mean to raster cells. Weighting should be done based on the polygons' cell coverage.
Problem visualized
Calculation for grid cell II
- Polygon A covers 10% of II.
- Polygon B covers 25% of II.
- Total polygon coverage of II is 35%.
So the value assigned for grid cell II will be:
(0.1/0.35)*5 + (0.25/0.35)*2 = 2.857
For grid cells I, III and IV it’s easy: They only get covered by one polygon and get their respective polgon's value assigned.
Reproducible Example
library("dplyr")
library("sf")
library("stars")
library("ggplot2")
nc_sf <- system.file("shape/nc.shp", package="sf") %>%
st_read() %>%
select(BIR74) %>%
rename(values = "BIR74")
nc_sf
# Simple feature collection with 100 features and 1 field
# Geometry type: MULTIPOLYGON
# Dimension: XY
# Bounding box: xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965
# Geodetic CRS: NAD27
# First 10 features:
# values geometry
# 1 1091 MULTIPOLYGON (((-81.47276 3...
# 2 487 MULTIPOLYGON (((-81.23989 3...
# 3 3188 MULTIPOLYGON (((-80.45634 3...
# 4 508 MULTIPOLYGON (((-76.00897 3...
# 5 1421 MULTIPOLYGON (((-77.21767 3...
nc_stars <- st_as_stars(
st_bbox(nc_sf),
nx = 20,
ny = 10
) %>%
.[nc_sf]
nc_stars
# stars object with 2 dimensions and 1 attribute
# attribute(s):
# Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
# values 0 0 0 0 0 0 91
# dimension(s):
# from to offset delta refsys point values x/y
# x 1 20 -84.3239 0.443344 NAD27 NA NULL [x]
# y 1 10 36.5896 -0.270766 NAD27 NA NULL [y]
# Error in find.package(if (is.null(package)) loadedNamespaces() else package, :
# there is no package called ‘extactextract’
# > nc_sf
# Simple feature collection with 100 features and 1 field
# Geometry type: MULTIPOLYGON
# Dimension: XY
# Bounding box: xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965
# Geodetic CRS: NAD27
# First 10 features:
# values geometry
# 1 1091 MULTIPOLYGON (((-81.47276 3...
# 2 487 MULTIPOLYGON (((-81.23989 3...
# 3 3188 MULTIPOLYGON (((-80.45634 3...
# 4 508 MULTIPOLYGON (((-76.00897 3...
# 5 1421 MULTIPOLYGON (((-77.21767 3...
# 6 1452 MULTIPOLYGON (((-76.74506 3...
# 7 286 MULTIPOLYGON (((-76.00897 3...
# 8 420 MULTIPOLYGON (((-76.56251 3...
# 9 968 MULTIPOLYGON (((-78.30876 3...
# 10 1612 MULTIPOLYGON (((-80.02567 3...
ggplot()+
geom_sf(data = nc_sf,
aes(fill = values)) +
ggtitle("polygons with values to be rasterized")
ggplot()+
geom_sf(data = st_geometry(nc_sf)) +
geom_stars(data = nc_stars, alpha = 0.8) +
theme(legend.position = "none") +
ggtitle("target raster")
Ideas on potential solutions
# Potentially helpful packages and functions
library("stars")
library("exactextractr")
library("terra")
library("raster")
stars::st_rasterize()
exactextractr::coverage_fraction()
terra::rasterize()
raster::rasterize()
I would prefer a stars::st_rasterize()
based solution, but I'm happy to bring in other packages and functions such as exactextractr::coverage_fraction()
or terra::rasterize()
or the raster
package. These seem to be the most promising to me.
My real life problem raster is pretty fine grained (around 690 000 cells), so I definitely need a solution that's not too computationally expensive. Hence, I'm afraid turning my raster into a polgyons to do all the calculations in sf
is not really viable.
"there is no package called ‘extactextract’"
message come from? It looks like a typo forexactextract
(look carefully, its "extact-" at the start) and there's no mention of that in the code, so, is that in one of the packages?? Note you also needdplyr
for therename
function.