4

I have two rasters, x and y, and I'd like to do calculations with them using the overlay function. For example,

MyFun <- function(x, y) x * y
res <- overlay(x, y, fun = MyFun)

This seems to work fine. Now, I want to add a conditional statement to my function like this:

MyFun <- function(x, y) {
    if(x > 0){ 
        x * y
    }else{
        abs(x) * y
    }
}

This gives a warning message like below:

Warning messages:
1: In if (x > 0) { :
  the condition has length > 1 and only the first element will be used

Clearly, R isn't happy with my code.

How should I write conditional statements in my functions so that they are compatible with overlay and rasters?

NB This is a toy example. My real task is more complicated, but the principle is the same.

4

You could use ifelse as an alternative to if and else blocks in a function. You can nest multiple statements in an ifelse and if you are trying to vectorize a problem, it is much cleaner. Note that an absolute abs statement on a zero value still returns zero so, I just used a very small number as a constant.

library(raster)
x <- raster(nrows=100, ncols=100)
  x[] <- runif(ncell(x))
y <- raster(nrows=100, ncols=100)
  y[] <- runif(ncell(y))

myFun <- function(x, y, p = 1.0e-08) { ifelse( x > 0, x * y, ifelse(x <= p * y)) }
( res <- overlay(stack(x, y), fun = myFun) )
1

A vectorized form would be

MyFun <- function(x, y) {
    i <- x < 0 
    x[i] <- abs(x) * y
    x[!i] <- x * y 
    x
}

But it might be more efficient (and certainly less error prone) to do

MyFun <- function(x, y) abs(x) * y
res <- overlay(x, y, fun = MyFun)

Or simply

res <- abs(x) * y

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.