Thursday, 24 March 2016

raster - R: Overlay using functions containing if/else statements


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.



Answer



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) )

No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...