I am trying to understand the difference between exact
and weights
argument in the extract
function in terra
package. My ultimate goal is to do a weighted average of raster within a polygon
library(terra)
f <- system.file("ex/lux.shp", package="terra")
v <- vect(f)
v <- v[1:2,]
z <- rast(v, resolution=.1, names="test")
values(z) <- 1:ncell(z)
rf <- system.file("ex/elev.tif", package="terra")
x <- rast(rf)
head(terra::extract(x, v, weight = T, touches = T))
ID elevation weight
1 1 NA 0.08
2 1 NA 0.17
3 1 529 0.30
4 1 542 0.52
5 1 547 0.74
6 1 535 0.18
head(terra::extract(x, v, exact = T, touches = T))
ID elevation fraction
1 1 NA 0.03471857
2 1 NA 0.11553771
3 1 529 0.23902885
4 1 542 0.45706171
5 1 547 0.68120503
6 1 535 0.12033581
Why the weight and fraction are different in both cases? When I try to compute the weighted mean:
terra::extract(x, v, fun = mean, weights = T, touches = T, na.rm = T)
ID elevation
1 1 NaN
2 2 NaN
terra::extract(x, v, fun = mean, exact = T, touches = T, na.rm = T)
ID elevation
1 1 467.3792
2 2 334.6856
Why does the first gives me NaN while the 2nd gives me some values. If I calculate it manually, I can see the weighted mean is what the exact = T
is giving me so what is the use of weights
argument?
test_df <- terra::extract(x, v, exact = T, touches = T, na.rm = T)
test_df %>%
dplyr::group_by(ID) %>%
dplyr::summarise(wt_mean = weighted.mean(elevation, fraction, na.rm = T))
ID wt_mean
1 467.
2 335.
In my version of "terra" the results are very similar.
library(terra)
#terra 1.6.53
f <- system.file("ex/lux.shp", package="terra")
v <- vect(f)
v <- v[1:2,]
z <- rast(v, resolution=.1, names="test")
values(z) <- 1:ncell(z)
rf <- system.file("ex/elev.tif", package="terra")
x <- rast(rf)
terra::extract(x, v, fun = mean, weights = T, touches = T, na.rm = T)
# ID elevation
#1 1 467.3934
#2 2 334.6551
terra::extract(x, v, fun = mean, exact = T, touches = T, na.rm = T)
# ID elevation
#1 1 467.3792
#2 2 334.6856
The documentation says that with "weights", "the approximate fraction of each cell" is used whereas with "exact", "the exact fraction" is used.
The reason for having both is in part because the argument "weights" predates the argument "exact". "weights" was kept because it could be faster and close enough in most cases.
P.S., you can also do
exactextractr::exact_extract(x, st_as_sf(v), "mean")
#[1] 467.3792 334.6855