Arcade fonction for calculate Median

1042
6
Jump to solution
05-26-2022 10:01 AM
User1RECS
New Contributor II

HI All,

can you please tell me how to calculate the Median Value of a liste in Arcade. there is not a fonction for calculate the median Value

0 Kudos
1 Solution

Accepted Solutions
JohannesLindner
MVP Frequent Contributor

Well, you just take Josh's answer and apply it to your table:

// load the whole feature class
var fs_buildings = FeatureSetByName($datastore, "BuildingFC", ["BlockID", "BuildingID", "BuildingHeight", "BuildingArea"], false)

// only select rows with the current feature's BlockID
var id = $feature.BlockID
var fs_buildings_block = Filter(fs_buildings, "BlockID = @ID")

// define a median function
function median(values) {
    var c = Count(values)
    var ordered = Sort(values)
    Console('Odd number of items. Returning central item')
    if(c%2 == 1) {
        return ordered[((c+1)/2)-1]
    }
    var a = ordered[(c/2)-1]
    var b = ordered[(c/2)]
    return (a+b)/2
}

// get your values
var values = []
for(var f in fs_buildings_block) {
    Push(values, f.BuildingHeight)
}

// calculate and return the median
return median(values)

Have a great day!
Johannes

View solution in original post

0 Kudos
6 Replies
jcarlson
MVP Esteemed Contributor

It does seem a bit of a limitation, but we can make up our own function.

We know that with an odd number of items of length n, the median is the item in position (n+1)/2.

Even numbers get a bit trickier, since we want a number halfway between the central two numbers. That is, ((n/2) + ((n+1)/2) / 2)

So what does this look like in Arcade?

First, we need to know if it's even or odd. That's easy enough, just use Count against your list and modulo divide by 2.

Second, we need to Sort the list. When using the Sort function without specifying a custom function will default to ordering your list items in ascending order.

Once sorted, we use one of the two formulas above depending on even or odd, then we return the value.

Final note: list indexes are 0-based, so we have to actually decrement the index we're returning.

Here's what it might look like with a sample input.

// Create a function to check even or odd
function isOdd(value){
    return Boolean(value % 2);
}

// Create an array, populate it with random numbers from 1-100
var some_list = [];

for (var x = 0; x < 100; x++){
    Push(some_list, Random()*100)    
}

// Sort list
var ordered = Sort(some_list)

// Get count of items
var c = Count(ordered)

// Check if even or odd return appropriate value
if (isOdd(c)){
    Console('Odd number of items. Returning central item')
    return ordered[((c+1)/2)-1]
} else {
    Console('Even number of items. Averaging central two')
    var a = ordered[(c/2)-1]
    var b = ordered[(c/2)]
    return (a+b)/2
}

 

Just to see that it works, here are the outputs with known "correct" values.

jcarlson_0-1653589902932.pngjcarlson_1-1653589918306.png

 

- Josh Carlson
Kendall County GIS
User1RECS
New Contributor II

Thank you so much for your response. i have a table with buildings by blocks and each building has its area and height. could you,please, give me the expression to calculate the median area for each block in a new field?

0 Kudos
JohannesLindner
MVP Frequent Contributor

Well, you just take Josh's answer and apply it to your table:

// load the whole feature class
var fs_buildings = FeatureSetByName($datastore, "BuildingFC", ["BlockID", "BuildingID", "BuildingHeight", "BuildingArea"], false)

// only select rows with the current feature's BlockID
var id = $feature.BlockID
var fs_buildings_block = Filter(fs_buildings, "BlockID = @ID")

// define a median function
function median(values) {
    var c = Count(values)
    var ordered = Sort(values)
    Console('Odd number of items. Returning central item')
    if(c%2 == 1) {
        return ordered[((c+1)/2)-1]
    }
    var a = ordered[(c/2)-1]
    var b = ordered[(c/2)]
    return (a+b)/2
}

// get your values
var values = []
for(var f in fs_buildings_block) {
    Push(values, f.BuildingHeight)
}

// calculate and return the median
return median(values)

Have a great day!
Johannes
0 Kudos
User1RECS
New Contributor II

It work perfectly. Thank you very much !!!!!

0 Kudos
User1RECS
New Contributor II

Help me, Please

0 Kudos
JohannesLindner
MVP Frequent Contributor

Dude, relax. We all have our own jobs to take care of before helping others here...


Have a great day!
Johannes
0 Kudos