# Raster Calculation with 2 Raster Layers [closed]

I am attempting to create a new raster layer based on the values of one raster layer using a formula that is conditional based on the values in another layer.

Two source layers:

``````> ndvi
class       : RasterLayer
dimensions  : 7741, 7611, 58916751  (nrow, ncol, ncell)
resolution  : 30, 30  (x, y)
extent      : 580185, 808515, 4191885, 4424115  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=utm +zone=15 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0
data source : C:/Users/xxx/AppData/Local/Temp/RtmpScc57V/raster/r_tmp_2019-04-22_112901_2168_61926.grd
names       : layer
values      : -1, 1  (min, max)

> pv
class       : RasterLayer
dimensions  : 7741, 7611, 58916751  (nrow, ncol, ncell)
resolution  : 30, 30  (x, y)
extent      : 580185, 808515, 4191885, 4424115  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=utm +zone=15 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0
data source : C:/Users/xxx/AppData/Local/Temp/RtmpScc57V/raster/r_tmp_2019-04-22_112936_2168_54474.grd
names       : layer
values      : 0, 1  (min, max)
``````

Layers each have the same dimensions, projection, and extent.

I want to create a new layer, e, that has the value:

``````0.97 when ndvi < 0.2
0.004 * pv + 0.986 when ndvi >= 0.2 and ndvi <= 0.5
0.99 when ndvi > 0.5
``````

My statement is:

``````e <- overlay(ndvi, pv, fun = function(ndvi, pv)
{
ifelse(ndvi < 0.2, 0.97, ifelse(ndvi > 0.5, 0.99, 0.004 * pv + 0.986))
}
)
``````

However, when I execute this, I receive the error:

Error in ifelse(ndvi > 0.5, 0.99, 0.004 * pv + 0.986) : argument "pv" is missing, with no default

How can I write this function so that it is compatible with overlay()? Is another approach more appropriate?

I'm somewhat new to R.

Other permutations attempted:

``````calc_e <- function(ndvi, pv)
{
ifelse(ndvi < 0.2, 0.97, ifelse(ndvi <= 0.5, 0.004 * pv + 0.986, 0.99))
}

e <- overlay(ndvi, pv, fun = calc_e)
``````

Same error was returned.

Then I tried:

``````ndvi_2 <- ndvi
ndvi_2[ndvi_2 < 0.2] <- 0.92

ndvi_m <- ndvi
ndvi_m[ndvi_m >= 0.2 && ndvi_m <= 0.5] <- 0.004 * pv + 0.986

ndvi_5 <- ndvi
ndvi_5[ndvi_5 > 0.5] <- 0.99
``````

The first and third subset assignments ran. However, I received an error on the second one "ndvi_m[ndvi_m >= 0.2 && ndvi_m <= 0.5] <- 0.004 * pv + 0.986"

Error in ndvi_m >= 0.2 && ndvi_m <= 0.5 : invalid 'x' type in 'x && y'

• Possible duplicate of R: Overlay using functions containing if/else statements Apr 22, 2019 at 19:50
• I did see that question/answer prior to posting my question. I even temporarily updated my syntax to use stack() as was used in that question's answer. However, I received the same error and subsequently reverted my syntax. Apr 22, 2019 at 20:11
• I would define your function outside of the `overlay` similar to the other answer for starters. As another troubleshooting step, I'd create separate rasters matching your conditions e.g. `ndvi2=ndvi ndvi2[ndvi2<0.2]=0.92` see here stackoverflow.com/questions/51716315/… Apr 22, 2019 at 20:28
• I separated out the function, but the error remained. I will continue with your next suggestion. Apr 22, 2019 at 20:33
• The solution was to use the function as defined by GISKid and pass that with the raster stack to calc() instead of overlay(). Thank you! Apr 23, 2019 at 16:06

Try this:

``````recalc<-function(ndvi,pv){
ifelse(ndvi<0.2,0.92,ifelse(ndvi >= 0.2 & ndvi <= 0.5,0.004 * pv + 0.986,ifelse(ndvi >0.5,0.99,NA)))
}

r<-stack(ndvi,pv)
res <- overlay(r, fun = recalc)
``````

As per updated comment the solution that worked was instead using `calc`:

``````res<-calc(r,fun=recalc)
``````

The recalc function is basically saying : If ndvi < 0.2, assign 0.92, if not look at this new ifelse based on these other conditions, assign this new value using this formula, if it doesn't meet this condition try ndvi >0.5 and assign 0.99 for anything that doesn't match those conditions assign it a value of "NA".

• Same error. I'm beginning to wonder if it is something in the data. I need to dig further into that. Apr 22, 2019 at 21:30
• Try adding a ... argument in the recalc function. You do not actually need to do anything with it as it is providing a passthrough to overlay. Apr 23, 2019 at 0:51

With help from @GISKid and @JeffreyEvans, the solution that finally worked was a combination of both of their comments.

``````calc_e = function(x) {
return(
ifelse(
x < 0.2,
0.97,
ifelse(
x >= 0.2 && x <= 0.5,
0.004 + x * 0.986,
ifelse(
x > 0.5,
0.99,
NA
)))) }

e <- calc(stack(ndvi, pv), fun = calc_e)
``````