Search code examples
rr-rasterterra

Arthematic operations using rasters throwing errors using terra package not with raster package


I am trying to do some calculation on raster using following code

library(terra)

f <- system.file("ex/elev.tif", package="terra") 
r <- rast(f)

r_n <- (r - global(r, fun = "min", na.rm=TRUE))/
  (global(r, fun = "max", na.rm=TRUE) - global(r, fun = "min", na.rm=TRUE))

It throws the following error

Error in data.frame(value, row.names = rn, check.names = FALSE) : duplicate row.names: 374, 356, 348, 378,...

But if I do it using raster R package, it runs fine like

library(raster)

r_raster <- stack(r)
r_n_raster <- (r_raster - minValue(r_raster))/
  (maxValue(r_raster) - minValue(r_raster))

What should I do to make the code run with terra package?


Solution

  • This happen because the ouput of global is a data.frame.You can simply convert the output of global to numeric with as.numeric or use the original summary function on the values of the raster:

    rmin <- as.numeric(global(r, fun = "min", na.rm=TRUE))
    rmax <- as.numeric(global(r, fun = "max", na.rm=TRUE))
    
    r_n <- (r - rmin)/
      (rmax - rmin)
    

    or

    rmin <-  min(values(r), na.rm=T)
    rmax <-  max(values(r), na.rm=T)
    

    EDIT

    A microbenchmark of the two proposed method with the example data:

    library(microbenchmark)
    microbenchmark(global=as.numeric(global(r, fun = "min", na.rm=TRUE)),
                   summary=min(values(r),na.rm=T))
    

    output

    Unit: microseconds
        expr    min      lq     mean median      uq     max neval cld
      global 2071.2 2157.40 2437.687 2223.6 2309.85 21725.9   100   b
     summary  729.2  756.35  844.381  794.4  824.15  5579.1   100  a