ar_result_calculations 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ ar_result_calculations (0.0.4) December 2, 2010
2
+
3
+ * Add calculations for median and mode
4
+
1
5
  ar_result_calculations (0.0.3) December 2, 2010
2
6
 
3
7
  * Add calculations for sample_variance and standard_deviation
data/README.textile CHANGED
@@ -30,6 +30,7 @@ p. All methods take one parameter (column name).
30
30
  |make_numeric|Coerces a column to be numeric. Useful if you have derived columns returned from a query that are not in the model definition and hence are otherwise returned as strings. Returns **self** so is composable|
31
31
  |sample_variance|Calculates the sample variance of a column (for active record result sets) or self (for an array)|
32
32
  |standard_deviation|Calculates the standard deviation of a column (for active record result sets) or self (for an array)|
33
+ |median|Calculates the median of a column (for active record result sets) or self (for an array)|
33
34
 
34
35
  h1. License
35
36
 
@@ -107,6 +107,35 @@ module ArResultCalculations
107
107
  Math.sqrt(variance)
108
108
  end
109
109
 
110
+ # Return the median of a column in an active record result set (or self)
111
+ #
112
+ # column: The column of which you want the median
113
+ # already_sorted: Is the data already sorted (default: true)
114
+ def median(column = nil, options = {:already_sorted => true})
115
+ options, column = column, nil if column && column.is_a?(Hash)
116
+ data = column ? map(&column.to_sym) : self
117
+ return nil if data.empty?
118
+ data = data.sort unless options[:already_sorted]
119
+ median_position = length / 2
120
+ length_is_even? ? data[median_position] : mean(data[median_position - 1..median_position])
121
+ end
122
+
123
+ # Return the mode(s) of a column in an active record result set (or self)
124
+ #
125
+ # column: The column of which you want the mode (or modes)
126
+ # find_all: Find all modes (default: true)
127
+ def mode(column = nil, options = {:find_all => false})
128
+ options, column = column, nil if column && column.is_a?(Hash)
129
+ data = column ? map(&column.to_sym) : self
130
+ histogram = data.inject(Hash.new(0)) { |h, n| h[n] += 1; h }
131
+ modes = nil
132
+ histogram.each_pair do |item, times|
133
+ modes << item if modes && times == modes[0] and options[:find_all]
134
+ modes = [times, item] if (!modes && times > 1) or (modes && times > modes[0])
135
+ end
136
+ modes && options[:find_all] ? modes[1..modes.size] : modes.try(:[], 1)
137
+ end
138
+
110
139
  # Force a column to be numeric. Useful if you have derived
111
140
  # columns from a query that is not part of the base model.
112
141
  #
@@ -141,6 +170,10 @@ module ArResultCalculations
141
170
  def is_float?(val)
142
171
  val.is_a?(Float) || val.is_a?(Rational)
143
172
  end
173
+
174
+ def length_is_even?
175
+ length % 2 == 0
176
+ end
144
177
  end
145
178
 
146
179
  module ClassMethods
@@ -1,3 +1,3 @@
1
1
  module ArResultCalculations
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ar_result_calculations
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 3
10
- version: 0.0.3
9
+ - 4
10
+ version: 0.0.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - Kip Cole