Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby on Rails method to calculate percentiles - can it be refactored?

I have written a method to calculate a given percentile for a set of numbers for use in an application I am building. Typically the user needs to know the 25th percentile of a given set of numbers and the 75th percentile.

My method is as follows:

def calculate_percentile(array,percentile)
 #get number of items in array
 return nil if array.empty?

 #sort the array
 array.sort!

 #get the array length
 arr_length = array.length

 #multiply items in the array by the required percentile (e.g. 0.75 for 75th percentile)
 #round the result up to the next whole number
 #then subtract one to get the array item we need to return
 arr_item = ((array.length * percentile).ceil)-1

 #return the matching number from the array
 return array[arr_item]

end

This looks to provide the results I was expecting but can anybody refactor this or offer an improved method to return specific percentiles for a set of numbers?

like image 304
simonyoung Avatar asked Jan 20 '26 04:01

simonyoung


1 Answers

Some remarks:

  • If a particular index of an Array does not exist, [] will return nil, so your initial check for an empty Array is unnecessary.
  • You should not sort! the Array argument, because you are affecting the order of the items in the Array in the code that called your method. Use sort (without !) instead.
  • You don't actually use arr_length after assignment.
  • A return statement on the last line is unnecessary in Ruby.
  • There is no standard definition for the percentile function (there can be a lot of subtleties with rounding), so I'll just assume that how you implemented it is how you want it to behave. Therefore I can't really comment on the logic.

That said, the function that you wrote can be written much more tersely while still being readable.

def calculate_percentile(array, percentile)
  array.sort[(percentile * array.length).ceil - 1]
end
like image 69
molf Avatar answered Jan 22 '26 16:01

molf



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!