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?
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.