[GIS] Setting masked pixel value in Google Earth Engine image export

exportgoogle-earth-enginemasking

I'm using Earth Engine to preprocess and download some NDVI data. I used a region of interest to clip the imagery to a geometry, and values from the Summary QA layer to mask out pixels that were of poor quality. However, when I export imagery to my drive account, download, and open in R, the areas that were masked have pixel values set to 0. I want those pixels to be set to NA's instead. A repeatable example:

// Generate Region of Interest
var ROI = ee.FeatureCollection('TIGER/2016/Counties')
  .filter(ee.Filter.eq('NAME', 'Waldo'));

// Create clipping function
var clipper = function(image){
  return image.clip(ROI);
};

// Create a QA mask function
var masker = function(image){ 
  var mask1 = image.select('SummaryQA').lte(1);
  var mask2 = image.select('SummaryQA').gte(0);
  return image.updateMask(mask1).updateMask(mask2);
};

// Compile the data
var dataset = ee.ImageCollection('MODIS/006/MOD13Q1')
                  .filter(ee.Filter.date('2018-01-01', '2018-12-31'))
                  .map(clipper);
print("MOD13Q1 Image Collection", dataset);

// Select just NDVI for repeatable code
var ndvi = dataset.map(masker).select('NDVI');
print("MOD13Q1 NDVI Collection",ndvi);


// PREPARE DATA FOR EXPORT
// Tyler Erickson provided the stacking function
// https://gis.stackexchange.com/a/254778/67264
var stackCollection = function(collection) {
  var first = ee.Image(collection.first()).select([]);

  // Write a function that appends a band to an image.
  var appendBands = function(image, previous) {
      var dateString = ee.Date(image.get('system:time_start')).format('yyyy-MM-dd');
      return ee.Image(previous).addBands(image.rename(dateString));
  };
  return ee.Image(collection.iterate(appendBands, first));
};
var ndvi_img = stackCollection(ndvi);

// Export the data
Export.image.toDrive({
  image: ndvi_img,
  description: 'MOD13Q1_comp_NDVI',
  scale: 250,
  region: ROI,
  fileFormat: 'GeoTIFF',
  formatOptions: {
    cloudOptimized: true
  }
});

If you take the product from Export.image.toDrive() and read it into R using…

library(raster)
NDVI = stack("/PATH/TO/MOD13Q1_comp_NDVI.tif")
plot(NDVI[[10]])

…you will find that areas outside the AOI, and areas that were masked, have values of 0, rather than NA. Is there a way to export imagery from Earth Engine with masked areas set to NA, or some other obvious non-standard value? I'd be fine with masked areas set to -99999 because they can get set to NA after the fact.

I looked into using the defaultValue argument described here but when I include that in the formatOptions an error is returned indicating that it isn't a valid argument ("defaultValue" is not a valid option, the image format "GEO_TIFF""may have the following options: cloudOptimized, fileDimensions").

Best Answer

Wasn't able to get this to work with an NA output, but based on this answer I settled on this solution, which can be used to set "masked" pixel values to whatever value is set in the unmask() function:

var ndvi_final = ndvi_img.unmask(-9999).clip(ROI);
Export.image.toDrive({
  image: ndvi_final,
  description: 'MOD13Q1_comp_NDVI',
  scale: 250,
  region: ROI,
  fileFormat: 'GeoTIFF',
  formatOptions: {
    cloudOptimized: true
  }
});