0

I have been struggling with an issue for several hours and I am currently having a very hard trying to find a workaround.

I want to use the overlay function of the raster package. This function combines multiple rasters (or raster layers of a stack) into a new raster according to a specific function, such as a mathematical function.

Here is a practical example:

library(raster)
# First we create an example raster stack with two layers
a <- matrix(rep(dnorm(1:100, 50, sd = 25)),
            nrow = 100, ncol = 100, byrow = TRUE)
env <- stack(raster(a * dnorm(1:100, 50, sd = 25) * 10000),
             raster(a * 1:100))
names(env) <- c("variable1", "variable2")
plot(env)

enter image description here

# Second, we combine them with a simple addition
raster3 <- overlay(env, fun = function(variable1, variable2) variable1 + variable2)
plot(raster3)

The resulting raster after combination with overlay

So, in the example above, our raster has two variables called variable1 and variable2, and we apply the formula variable1 + variable2 on them.

The problem

I am trying to use overlay within a function, in which I have:

  • the input raster stack (the number of layers is variable, as well as the names of layers). A typical example is the stack env above.
  • the formula (the formula is always written based on layer names of the input raster stack). Typical examples are variable1 + variable2 or variable1 * variable2 + 3 * variable1.

My (unsuccessful) attempts

I was able to use a formula previously stored as a string in an object:

form <- "variable1 + 3 * variable2"
raster4 <- overlay(env, fun = function(variable1, variable2) eval(parse(text = form)))

This works; however, you can notice that I still had to specify variable1 and variable2 as arguments. I am not able to figure out how to automatically provide layer names as arguments in fun.

I tried:

overlay(env, fun = function(...) eval(parse(text = form)))
overlay(env, fun = function(names(env)) eval(parse(text = form)))

but these obviously did not work. I am already using the terrible eval(parse()) procedure within the function, I would like to find a solution which will not require me to write a general eval(parse()) script encompassing the whole overlay.

Any insights will be greatly appreciated ;)

Boris Leroy
  • 460
  • 4
  • 14

2 Answers2

0

Here is an ugly workaround using eval(parse())

The aim is to create a function which adapts to the input raster and formula.

  • Example with the formula variable1 + variable2

.

form <- "variable1 + variable2"
input.raster <- env
eval(parse(text = paste("custom.overlay <- function(",
                        paste(names(input.raster), collapse = ", "),
                        ") {",
                        form,
                        "}"
)))
raster4 <- overlay(env, fun = custom.overlay)
plot(raster4)

enter image description here

  • Another example with the formula variable1^2 + 3 * variable2

.

form <- "variable1^2 + 3 * variable2"
input.raster <- env
eval(parse(text = paste("custom.overlay <- function(",
                        paste(names(input.raster), collapse = ", "),
                        ") {",
                        form,
                        "}"
)))
raster5 <- overlay(env, fun = custom.overlay)
plot(raster5)

enter image description here

It works in both cases. But it's not a very elegant solution

Boris Leroy
  • 460
  • 4
  • 14
0

You should not refer to the variable names, but to their position. Then you can do, for example:

library(raster)
a <- matrix(rep(dnorm(1:100, 50, sd = 25)), nrow = 100, ncol = 100, byrow = TRUE)
env <- stack(raster(a * dnorm(1:100, 50, sd = 25) * 10000), raster(a * 1:100))

v <- overlay(env, fun=function(x,y) x * y + 3 - sqrt(y / x))

And without the "eval(parse(text = form)" business, your example works fine for me:

raster4 <- overlay(env, fun = function(variable1, variable2) variable1 + 3 * variable2)
Robert Hijmans
  • 40,301
  • 4
  • 55
  • 63
  • Thanks for your answer @RobertH . Unfortunately this is used inside [a package](https://github.com/Farewe/virtualspecies/blob/master/R/generateSpFromFun.R) where users can provide a formula as a string. I can never be sure about the position of variables in both the formula and the raster stack, which is why I wanted to work with names. I really do not know how to set up a function for the argument `fun` of `overlay` without using `eval(parse())`. – Boris Leroy Jun 27 '16 at 09:40