4

I have a FeatureCollection where I would like to take the mean of multiples properties for each feature.

I did not find so far an elegant way to do this, currently I am using using the map function, mapping over each feature a number operation like: var1.add(var).divide(2).

Is there a more elegant way to aggregate over properties in a featureCollection? The problem with my solution is that I can't handle null values, which unfortunately happen often in my dataset. Indeed, using the add() function will fail in that case, see example below.

Code: https://code.earthengine.google.com/9944b02bc720859307811571fcc3cb0e

 var features = ee.FeatureCollection([
  ee.Feature(null, {var1: 1, var2: 2}),
  ee.Feature(null, {var1: 2, var2: 3}),
  ee.Feature(null, {var1: 1, var2: null})]);

print(features)


/// mean
var getMean = function(feature) {
  var var1 = ee.Number(feature.get('var1'));
  var var2 = ee.Number(feature.get('var2'));


  return feature.set({mean: var1.add(var2).divide(5)});
}


// Works:
var test_agg = features.limit(2).map(getMean);
print(test_agg)

// Does not work:
var test_agg2 = features.map(getMean);
print(test_agg2)
  • what do you mean by more elegant? faster? easier? – Rodrigo E. Principe Apr 24 '18 at 2:01
  • I mean 1) more scalable (as if I were to aggregate over 100 properties, I would need to repeat a line 100 times) and 2) not suffering from the null issue, that if a single feature contains a single property with null, the whole code fails, Thanks @RodrigoE.Principe ! – Matifou Apr 24 '18 at 5:16
3
+50

I've made a function to perform that task on the Code Editor. Source code can be found here: https://earthengine.googlesource.com/users/fitoprincipe/geetools/+/master

How to use it:

var tools = require('users/fitoprincipe/geetools:tools')

var f1 = ee.Feature(null, {var1: 1, var2: 2, numprop:4})
var f2 = ee.Feature(null, {var1: 2, var2: 3, strprop: 'jojo'})
var f3 = ee.Feature(null, {var1: 1, var2: null})

var features = ee.FeatureCollection([f1, f2, f3]);

print(features)

// The function we are going to use is called `aggregate_properties`

// Sum over a FeatureCollection
var sum_col = features.map(tools.aggregate_properties({
  properties:['var1', 'var2'],
  reducer: 'sum',
  name: 'sum'
}))
print(sum_col)

// Mean over a FeatureCollection
var mean_col = features.map(tools.aggregate_properties({
  properties:['var1', 'var2'],
  reducer: 'mean',
  name: 'custom_name'
}))
print(mean_col)

// Mean over one feature
var mean_feat = tools.aggregate_properties({
  name: 'mean_one_feature'
})(f1)
print(mean_feat)

link: https://code.earthengine.google.com/2ecbedacfc1f8a566025147c00f35077

  • awesome, exactly what I needed, thanks so much!!!! – Matifou Apr 24 '18 at 18:49
  • I am not sure about the 'map' option? In my real case application, it would actually discard the first variable I want to aggregate over, in a FeatureCollection? Is there any chance you could add a few quick comment in the source code of the function? Thanks!!!! – Matifou Apr 24 '18 at 20:29
  • Indeed, when I map propertyNames() to my FC, it does add system:index, but in my case it is returned as last in the list, not first (no idea why...). Thanks!!! – Matifou Apr 24 '18 at 20:46
  • @Matifou you're right, it could be added at last position, I'll try to modify the code in that direction. Thank you – Rodrigo E. Principe Apr 24 '18 at 22:09
  • @Matifou I have made the change, now works for both cases and don't even need to specify if it is for map or not, just use it. Made an update on the example. – Rodrigo E. Principe Apr 25 '18 at 2:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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