Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I perform neighborhood analysis in terra or raster and keep the same NA cells of the input?

Tags:

r

r-raster

terra

I want to perform a neighborhood analysis in R to smooth the layer I have but keeping all the NAs of the input raster intact.

However, when I do, for instance, the following, the calculation "propagates" over the NA values - what it is an undesiderable behavior, in my case.

library(terra)
library(dplyr)

# load example raster in metric system
f <- system.file("ex/elev.tif", package="terra")
r <- rast(f) %>% 
  terra::project("EPSG:32631")

# focal
neigh <- terra::focal(r, w = 7, fun = "mean")

# plot
plot(c(r, neigh))

enter image description here

Update: Following the suggestion made by @dww below, I could use terra::mask. A way to deal with that, then, would be:

# focal
neigh <- terra::focal(r, w = 7, fun = "mean") %>% 
  terra::mask(mask = r)

# plot
plot(c(r, neigh))

enter image description here

Is there another way out avoid the propagation of values to NA cells within focal?
(here it is a simple example of a square filter to calculate the mean, but I am searching something that would be usefull for all types of filter, e.g. any matrix defined by terra::focalMat())
Should I deal with that when defining the weight matrix?

like image 800
bniebuhr Avatar asked Oct 25 '25 04:10

bniebuhr


1 Answers

With terra the focal method has an argument na.policy that can be set to one of "all", "only" or "omit".

library(terra)
#terra 1.5.6
v <- vect(system.file("ex/lux.shp", package="terra"))
r <- rast(system.file("ex/elev.tif", package="terra"))
r[45:50, 45:50] <- NA

f1 <- focal(r, 7, "mean", na.policy="omit", na.rm=TRUE)   
plot(f1, fun=lines(v))

enter image description here

This is equivalent, but possibly more efficient, to using focal and mask:

f2 <- focal(r, 7, "mean", na.rm=TRUE) |> mask(r)
like image 54
Robert Hijmans Avatar answered Oct 26 '25 18:10

Robert Hijmans



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!