rastermaskterra

terra mask raster by categorical raster


I have a ginormous raster (rasterA) with values in the range 1:928863, and I want values in another raster, rasterB, set to NA where values(rasterA) > 300.

the rasters are big:

library(terra)
set.seed(0)
rasterA <- rast(nrows=42893, ncols=52031)
rasterB <- rasterA
values(rasterA) <- sample(1:928563, ncell(rasterA), replace=TRUE))
values(rasterB) <- 1

My current approach (which has been running several hours and show no sign of finishing) is:

rasterA <- subst(rasterA, 300:928863, NA)

which I was then going to follow with:

rasterB  <- mask(rasterB, rasterA)

While that code runs, I thought: what if I could make rasterA categorical (a very fast operation), and mask rasterB by the categories? like this:

leveller <- data.frame(id = 1:928863, dist= c(rep("good", 300), rep(NA, 928563)))
levels(rasterA) <- leveller
rasterB <- mask(rasterB, rasterA)

that appears to run, but doesn't produce what I hoped for.

here is an example that is small enough to run: I want to mask my raster (r) by the categorical raster (rf), where rf == NA

library(terra)
set.seed(0)
rf <- rast(nrows=10, ncols=10)
values(rf) <- sample(3, ncell(rf), replace=TRUE)
cls <- data.frame(id=1:3, cover=c("forest", "water", NA))
levels(rf) <- cls

r <- rast(nrows=10, ncols=10)
values(r) <- 1

r <- mask(r, rf)

r is still a raster with all values 1

So, can I mask by factor levels of a categorical raster? Or is there a faster way for me to do the masking I originally wanted?


Solution

  • I like your idea of setting the categorical label to NA for some cells. However, that does not change the underlying raster value; and that is what mask responds to.

    This is how I would approach it

    Example data

    library(terra)
    rB <- rA <- rast(nrows=100, ncols=100)
    rA <- init(rA, "cell")
    values(rB) <- 1
    

    Solution

    rM <- mask(rB, rA > 1000, maskvalue=FALSE)
    

    You could also do

    f <- \(x) { 
       x[x[,2] <= 1000, 1] <- NA
       x[,1]
    }
    x <- app(c(rB, rA), f)
    

    But that is more convoluted and probably slower.