8

I want to fill the NA values using the average values of the nearest neighbors:

r <- raster(matrix(1:16, nrow=8, ncol=8))
r[r==12] <- NA
12

You can fill in the NA values using the focal function with the na.rm argument set to FALSE and pad to TRUE.

library(raster)
  r <- raster(matrix(1:16, nrow=8, ncol=8))
  r[r==12] <- NA

Function to replace the focal value with the mean of a 3x3 window if NA. If the window size increases the index value [i] needs to change as well (eg., for a 5x5 window the index would be 13).

fill.na <- function(x, i=5) {
  if( is.na(x)[i] ) {
    return( round(mean(x, na.rm=TRUE),0) )
  } else {
    return( round(x[i],0) )
  }
}  

Pass the fill.na function to raster::focal and check results. The pad argument creates virtual rows/columns of NA values to keep the vector length constant along the edges of the raster. This is why we can always expect the fifth value of the vector to be the focal value in a 3x3 window thus, the index i=5 in the fill.na function.

r2 <- focal(r, w = matrix(1,3,3), fun = fill.na, 
            pad = TRUE, na.rm = FALSE )

as.matrix(r)
as.matrix(r2)
  • Thanks, I think this function takes the mean of the every 3 by 3 pixels and smooths the whole raster. I want to fill the gaps of the NA cell only. – Geo-sp Feb 16 '16 at 21:49
  • Yes, but you can write your own function that only replaces NA values. In this case na.rm would be FALSE. This is what the fun argument is for. – Jeffrey Evans Feb 17 '16 at 3:05
  • Thanks for the answer! do you know how I can apply this to a raster stack? I want to use that for each layer in of stack. Thanks! – Geo-sp Feb 17 '16 at 17:14
  • You will have to iterate through the stack using a for loop and an index and either replace each raster in the stack (eg., r[[1]] <- my.function(r[[1]]) ) or create a new stack with each filled raster. – Jeffrey Evans Feb 17 '16 at 18:56
  • 1
    If you want to do this in R it is likely that you will have to perform multiple passes in order to fill in all the gaps. However, this is not a very satisfying answer for filling areas that represent large data voids. An interpolation approach would certainly produce better results. Without coding a specific model in R, there are no out of the box solutions. There is an interpolation based nodata filling routine available in SAGA GIS. – Jeffrey Evans Aug 11 '17 at 20:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.