Search code examples
roverlaycalc

Band math with calc and / or overlay returning single-valued images


When I try to run band math the result is always an image of a color and the values min and max very different from the one predicted. I did not find any question here that showed this problem. I worked out this way

r.stack <- stack("path to raster file"))

I use resampling instead of crop to cut out the white edges that were in the original images

prj <- "+proj=utm +zone=23 +south +datum=WGS84 +units=m"
r <- raster(res=11.47, ext=extent(c(301496,  323919, 9888968, 9913982)), crs=prj, vals=NA
r.stack <- resample(r.stack, r)

After that the images have this configuration:

> class       : RasterBrick 
> dimensions  : 2181, 1955, 4263855, 4  (nrow, ncol, ncell, nlayers)
> resolution  : 11.47, 11.47  (x, y)
> extent      : 301496, 323919.8, 9888966, 9913982  (xmin, xmax, ymin, ymax)
>coord. ref. : +proj=utm +zone=23 +south +datum=WGS84 +units=m +ellps=WGS84 +towgs84=0,0,0 
>data source : in memory
>names       : l.1, l.2, l.3, l.4
>min values  :       -36.12217,           -45.12768,   -46.30455,                       -35.26328 
>max values  :      10.567671,         4.050200,         3.878345,                       11.613799

and than use the function below for calc

f <- function(x){
      (x[[2]])/(x[[1]])
}

s <- r.stack[[c(1,2)]]
r2 <- calc(s, f)

and I also run overlay whit the fun

f <- function(x,y){
     y/x
}
r2 <- overlay(r.stack[[1]], r.stack[[2]], fun= f)

Any of the methods result in a image of one value

Am I missing some steps?


Solution

  • Here is your code with some example data (without that it is hard to answer questions). I have simplified one function, a bit, but the results are the same.

    library(raster)
    b <- brick(system.file("external/rlogo.grd", package="raster"))
    b <- b/10 + 1
    
    f <- function(x){ x[2]/ x[1] }
    s <- b[[c(1,2)]]
    r1 <- calc(s, f)
    
    f <- function(x,y){ y / x }
    r2 <- overlay(b[[1]], b[[2]], fun= f)
    

    Or simply

    r3 <- b[[2]] / b[[1]]   
    r3
    #class       : RasterLayer 
    #dimensions  : 77, 101, 7777  (nrow, ncol, ncell)
    #resolution  : 1, 1  (x, y)
    #extent      : 0, 101, 0, 77  (xmin, xmax, ymin, ymax)
    #coord. ref. : +proj=merc +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0 
    #data source : in memory
    #names       : layer 
    #values      : 0.7692308, 1.7  (min, max)
    

    r1 and r2 are the same.

    The reason that you get a "single color" is because most values are near 1, but there are a few big outliers; probably because of a division by a number between -1 and 1? This might illustrate it:

    q <- quantile(r3, c(0.1, 0.9))
    d <- clamp(r3, q[1], q[2])
    plot(d)
    

    And look at the extremes

    i <- which.max(r3)
    b[i][,2:1]