Search code examples
rgeospatialterra

using terra::ifel in a function


I'm new to terra and have to cycle a large number of rast objects through a byzantine set of nested conditionals. I've written it all out using ifel but unsure how to make a function that I can use lapp with.

r <- c(rast(matrix(1:25, nrow=5, ncol=5)),
       rast(matrix(11:35, nrow=5, ncol=5)))
names(r)[2] <- "lyr.2"

r2 <- ifel(r["lyr.1"] > 20,100,
           ifel(r["lyr.1"] <=5 & r["lyr.2"]>10, 200,
                ifel(r["lyr.2"] <= 10 & r["lyr.1"] > 5, 300,
                     9999)))
plot(r2)

Assuming that r will be a raster with consistently named layers, how can I make r2 using a function and lapp?

Many thanks.


Solution

  • You make a function like this

    f <- function(x) {
        ifel(x["lyr.1"] > 20,100,
         ifel(x["lyr.1"] <=5 & x["lyr.2"]>10, 200,
          ifel(x["lyr.2"] <= 10, 300, 9999)))
    }
    
    r2 <- f(r)
    

    And if you have a list or SpatRasterDataset you can use it with lapply.

    x <- list(r,r) 
    # or
    # x <- sds(r, r)
    y <- lapply(x, f)
    

    If you want to use lapp you can rewrite the function like this

    ff <- function(x, y) {
        ifelse(x > 20, 100,
         ifelse(x <=5 & y > 10, 200,
          ifelse(y <= 10, 300, 9999)))
    }
    

    and do

    x <- sds(r, r)
    z <- lapp(x, ff)