Search code examples
rraster

Combine two raster layers, setting NA values in non-mask layer to 0 where mask layer is not NA


I have two raster layers that I wish to combine into one. Let's call them mask (with values 1 and NA), and vrs.

library(raster)
mask <- raster(ncol=10, nrow=10)
mask[] <- c(rep(0, 50), rep(1, 50))
mask[mask < 0.5] <- NA
vrs <-raster(ncol=10, nrow=10)
vrs[] <- rpois(100, 2)
vrs[vrs >= 4] <- NA

I wish to combine two big layers, but for the sake of understanding these small examples are ok. What I wish to do is to set the pixel values of my output layer to zero for those pixels where mask layer is 1 and vrs layer is NA. All other pixels should remain with the values of original vrs.

This is my only thought as to how:

zero.for.NA <- function(x, y, filename){
  out <- raster(y)
  if(canProcessInMemory(out, n = 4)) { #wild guess..
    val <- getValues(y) #values
    NA.pos <- which(is.na(val)) #positiones for all NA-values in values-layer
    NA.t.noll.pos<-which(x[NA.pos]==1) #Positions where mask is 1 within the 
                                       #vector of positions of NA values in vrs
    val[NA.pos[NA.t.noll.pos]] <- 0 #set values layer to 0 where condition met
    out <- setValues(out, val)
    return(out)
  } else { #for large rasters the same thing by chunks
    bs <- blockSize(out)
    out <- writeStart(out, filename, overwrite=TRUE)
    for (i in 1:bs$n) {
      v <- getValues(y, row=bs$row[i], nrows=bs$nrows[i])
      xv <- getValues(x, row=bs$row[i], nrows=bs$nrows[i])
      NA.pos <- which(is.na(v))
      NA.t.noll.pos <- which(xv[NA.pos]==1)
      v[NA.pos[NA.t.noll.pos]] <- 0
      out <- writeValues(out, v, bs$row[i])
    }
    out <- writeStop(out)
    return(out)
  }
}

This function did work on the small example and seems to work on the bigger ones. Is there a faster/better way of doing this? Some way that is better for larger files? I will have to use this on many sets of layers and I would appreciate any help in making the process safer and or quicker!


Solution

  • I'd use cover():

    r <- cover(vrs, mask-1)
    plot(r)
    

    enter image description here