1

I am using rgee for the Google Earth Engine API in R to reduce an image collection and obtain the max value for each cell - this works fine.

Is there an equivalent function to "which.max" R function, that would tell me for each cell which image in the collection contained the max value?

E.g. In a year of daily EVI images, for each cell which of the 365 images contained the maximum value. Reducer.max simply gives the value of the image which contained the max.

1 Answer 1

2

You can use the ee.Reducer.max() reducer as the input to ee.ImageCollection.reduce() with the numInputs parameter to retain the values of additional bands from the "max image".

Here is an example that adds date bands (milliseconds from Unix epoch and YYYYMMdd) to each image in a MODIS NDVI collection and then reduces the collection to NDVI max and retains the date bands which can be used to determine date of the max NDVI (per-pixel) or even find the original image using a filter on system:time_start that matches a value in the "millis" band.

// Adds milliseconds from Unix epoch and date encoded as YYYYMMdd
// as bands to a given image.
function addDateBands(img) {
  var imgDate = img.date();
  var millis = imgDate.millis();
  var date = ee.Number.parse(imgDate.format('YYYYMMdd'));
  var dateBands = ee.Image([millis, date]).rename(['millis', 'date']).toLong();
  return img.addBands(dateBands).set('date', date);
}

// Applies per-pixel max reduction of image collection that returns the max
// of the target band and also the corresponding band values from the max image.
function getMaxAndOthers(col, maxBand, otherBands) {
  var theseBands = [maxBand].concat(otherBands);
  col = col.select(theseBands);
  return col.reduce(ee.Reducer.max(theseBands.length)).rename(theseBands);
}

// Import a MODIS NDVI collection for the year 2021.
var ndvi = ee.ImageCollection('MODIS/061/MOD13Q1')
  .filterDate('2021-01-01', '2022-01-01')
  .select('NDVI');

// Add date bands to each image.
var ndviWithDate = ndvi.map(addDateBands);

// Get per-pixel max NDVI value and corresponding band values from max image.
var ndviMax = getMaxAndOthers(ndviWithDate, 'NDVI', ['millis', 'date']);

// Visualize max NDVI and corresponding date band (YYYYMMdd).
Map.addLayer(
  ndviMax,
  {bands: ['NDVI'], min: 0, max: 9000, palette: ['white', 'green']},
  'NDVI max');
Map.addLayer(
  ndviMax,
  {bands: ['date'], min: 20210101, max: 20211219},
  'Date for NDVI max');

Code Editor script

3
  • Note that you may need to translate the EE JavaScript API code above into rgee conventions; the concepts/workflow still apply. Commented Aug 17, 2022 at 17:28
  • This tutorial is relevant: developers.google.com/earth-engine/tutorials/community/… Commented Aug 17, 2022 at 17:39
  • Thank you so much - this is exactly what I was looking for! I should be able to translate that into rgee code and get what I want.
    – Ray
    Commented Aug 18, 2022 at 7:45

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.