lib/easystats.rb
class Array
def mean
return if empty?
sum / count.to_f
end unless method_defined? :mean
alias_method :average, :mean unless method_defined? :average
def weighted_moving_average
return if empty?
return first if one?
weighted_sum = 0
sum = 0
index = 0
each do |element|
weighted_sum = weighted_sum + (index * element)
sum += index
index += 1
end
weighted_sum.to_f / sum
end unless method_defined? :weighted_moving_average
def median
return if empty?
data = sort
halfway = data.count / 2
if data.count.even?
(data[halfway] + data[halfway - 1]) / 2.0
else
data[halfway]
end
end unless method_defined? :median
def mode
return if empty?
return first if one?
frequencies = each_with_object(Hash.new(0)) { |v, k| k[v] += 1 }
mode_value, mode_frequency = frequencies.max_by { |_, freq| freq }
# Check if any other value has the same frequency
return if frequencies.values.count(mode_frequency) > 1
mode_value
end unless method_defined? :mode
def probability_distribution
return if empty?
total = count.to_f
uniq.inject({}) { |result, item|
result.update({ item => count(item) / total })
}
end unless method_defined? :probability_distribution
def range
return if empty?
max - min
end unless method_defined? :range
def standard_deviation
return if empty?
return 0 if one?
Math::sqrt sum_of_deviations_squared / (count - 1)
end unless method_defined? :standard_deviation
def sum
reduce :+
end unless method_defined? :sum
def variance
return if empty?
sum_of_deviations_squared / count.to_f
end unless method_defined? :variance
protected
def sum_of_deviations_squared
mean = self.mean
inject(0) { |total, number| total + ((number - mean) ** 2) }
end
end