1

I have a raster stack having different raster layers with band names (e.g. B1, B2, B3, ….…. Bn). I need to prepare a new categorical raster with band name (for each pixels) having maximum pixel values selected from a stack.

I have used the following code:

library(raster) 
files <- list.files("E:/Red Panda/TIF/", pattern='tif$', full.names=TRUE ) 
Raster_stack <- stack(files) 
pixelMaxBand.ras <- whiches.max(Raster_stack) 

But I found this type of error:

Error in .local(x, ...) : you can use only use this function for an object with less than 10 layers.

With “whiches.max” function for layers greater than 10, can you suggest the appropriate code?

1
  • I have a multiband raster stack and I want to find the band number of the maximum value for each pixel. For this, I have used the following code: library(raster) files <- list.files("E:/Red Panda/TIF/", pattern='tif$', full.names=TRUE ) Raster_stack <- stack(files) pixelMaxBand.ras <- whiches.max(Raster_stack) But I found this type of error: Error in .local(x, ...) : you can use only use this function for an object with less than 10 layers. With “whiches.max” function for layers greater than 10, can you please suggest me the appropriate code? Commented Dec 12, 2021 at 7:57

2 Answers 2

4

You can pass the base function which.max to raster::calc. The vector length should remain constant because raster::calc does not remove NA's unless you pass it a function that supports an na.rm argument. What you are after is a simple as:

library(raster)

r <- do.call(raster::stack, replicate(6, 
       raster::raster(matrix(runif(1000), 100, 100))))

( rmax <- calc(r, which.max) )  

The terra package allows you to apply which.max directly to the raster object. I recommend starting to move your workflows to terra as it is the eventual replacement for raster and is considerably faster with a better function interface.

library(terra)
r <- rast(r)
( rmax <- which.max(r) ) 
5
  • Again I run the code as follows: #Get the names of all the files with extension ".asc" of the folder files <- list.files("C:\\Users\\user\\Desktop\\ASCII/", pattern='asc$', full.names=TRUE ) files Raster_stack <- stack(files) Raster_stack names(Raster_stack) plot(Raster_stack) # Identify pixel-wise band with max value new_cat_raster <- raster::calc(Raster_stack, fun=which.max, na.rm=FALSE) and the result is: Error in .calcTest(x[1:5], fun, na.rm, forcefun, forceapply) : cannot use this function. Perhaps add '...' or 'na.rm' to the function arguments? How can I remove it? Commented Dec 13, 2021 at 16:09
  • Code: new_cat_raster <- raster::calc(Raster_stack, fun=which.max, na.rm=FALSE) and the error is: Error in .calcTest(x[1:5], fun, na.rm, forcefun, forceapply) : cannot use this function. Perhaps add '...' or 'na.rm' to the function arguments? Commented Dec 13, 2021 at 16:11
  • @ShivaPariyar at some point the calc function has changed it's NA handling with the na.rm argument. Just omit it as, the default behavior of calc is to retain NA's so, the vector length should remain constant (see edit to my answer). Commented Dec 13, 2021 at 16:55
  • The issue here is that which.max does not have a na.rm argument, so you should not provide it. Commented Dec 14, 2021 at 2:59
  • @Robert Hijmans Thank you so much. Commented Dec 21, 2021 at 16:55
1

You can use which.max directly

Example data

library(raster)
f <- stack(system.file("external/rlogo.grd", package="raster")) 
s <- stack(f/2, f, f, f)
nlayers(s)
#[1] 12
# add some `NA`s
s[[12]] <- setValues(s[[12]], NA)

(r <- which.max(s))   
#class      : RasterLayer 
#dimensions : 77, 101, 7777  (nrow, ncol, ncell)
#resolution : 1, 1  (x, y)
#extent     : 0, 101, 0, 77  (xmin, xmax, ymin, ymax)
#crs        : +proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs 
#source     : memory
#names      : layer 
#values     : 1, 6  (min, max)

As Jeffrey Evens pointed out, you can also do:

rc <- calc(s, which.max)

The reason that you can use whiches.max with no more then 9 layers (it could have been 10) is that it also returns ties:

(rr <- whiches.max(s[[1:9]]))
#class      : RasterLayer 
#dimensions : 77, 101, 7777  (nrow, ncol, ncell)
#resolution : 1, 1  (x, y)
#extent     : 0, 101, 0, 77  (xmin, xmax, ymin, ymax)
#crs        : +proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m #+no_defs 
#source     : memory
#names      : layer 
#values     : 47, 123456789  (min, max)

47 means that layers 4 and 7 both have the maximum value.

Also note that which.max always ignores NAs:

which.max(c(NA, 1:5, NA, 3))
#[1] 6

And with terra:

library(terra)    
f <- system.file("ex/logo.tif", package="terra")
x <- rast(c(f, f, f, f))
x[[1:3]] <- x[[1:3]] / 2
which.max(x)
#class       : SpatRaster 
#dimensions  : 77, 101, 1  (nrow, ncol, nlyr)
#resolution  : 1, 1  (x, y)
#extent      : 0, 101, 0, 77  (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs 
#source      : memory 
#name        : which.max 
#min value   :         1 
#max value   :         6 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.