Module: BasicStatistics

Included in:
Array, Vector
Defined in:
lib/feldtruby/array/basic_stats.rb

Instance Method Summary collapse

Instance Method Details

#averageObject



11
# File 'lib/feldtruby/array/basic_stats.rb', line 11

def average; mean(); end

#inter_quartile_rangeObject



59
60
61
62
# File 'lib/feldtruby/array/basic_stats.rb', line 59

def inter_quartile_range
  q1, q2, q3 = quartiles
  q3 - q1
end

#meanObject



6
7
8
9
# File 'lib/feldtruby/array/basic_stats.rb', line 6

def mean
  return 0 if self.length == 0
  self.sum / self.length.to_f
end

#medianObject



13
14
15
16
17
18
19
20
21
22
# File 'lib/feldtruby/array/basic_stats.rb', line 13

def median
  return nil if length == 0
  sorted = self.sort
  if self.length % 2 == 0
    mid = self.length / 2
    (sorted[mid-1] + sorted[mid])/2.0
  else
    sorted[self.length/2.0]
  end
end

#quantile_at_ratio(p) ⇒ Object

Calculate the quantile at a given ratio (must be between 0.0 and 1.0) assuming self is a sorted array. This is based on the type 7 quantile function in R.



37
38
39
40
41
42
43
44
45
46
47
# File 'lib/feldtruby/array/basic_stats.rb', line 37

def quantile_at_ratio(p)
  n = self.length
  h = (n - 1) * p + 1
  hfloor = h.floor
  if h == hfloor
    self[hfloor-1]
  else
    x_hfloor = self[hfloor-1]
    x_hfloor + (h - hfloor)*(self[hfloor] - x_hfloor)
  end
end

#quantilesObject

Calculate the values that cuts the data into 0%, 25%, 50%, 75% and 100%. This corresponds to the min, 1st quartile, 2nd quartile, 3rd quartile and the max.



26
27
28
29
30
31
32
33
# File 'lib/feldtruby/array/basic_stats.rb', line 26

def quantiles
  return [nil, nil, nil, nil, nil] if length == 0
  sorted = self.sort
  q1 = sorted.quantile_at_ratio(0.25)
  q2 = sorted.quantile_at_ratio(0.50)
  q3 = sorted.quantile_at_ratio(0.75)
  return sorted.first, q1, q2, q3, sorted.last
end

#quartilesObject

Calculate the three quartiles of the array.



50
51
52
53
54
55
56
57
# File 'lib/feldtruby/array/basic_stats.rb', line 50

def quartiles
  return [nil, nil, nil] if length == 0
  sorted = self.sort
  q1 = sorted.quantile_at_ratio(0.25)
  q2 = sorted.quantile_at_ratio(0.50)
  q3 = sorted.quantile_at_ratio(0.75)
  return q1, q2, q3
end

#rmsObject



89
# File 'lib/feldtruby/array/basic_stats.rb', line 89

def rms; self.root_mean_square(); end

#rms_from(other) ⇒ Object

Root mean square from another vector



133
134
135
# File 'lib/feldtruby/array/basic_stats.rb', line 133

def rms_from(other)
  Math.sqrt(sum_squared_error(other))
end

#rms_from_scalar(scalar) ⇒ Object



91
92
93
# File 'lib/feldtruby/array/basic_stats.rb', line 91

def rms_from_scalar(scalar)
  Math.sqrt( self.map {|v| (v-scalar)**2}.mean )   
end

#root_mean_squareObject



85
86
87
# File 'lib/feldtruby/array/basic_stats.rb', line 85

def root_mean_square
  Math.sqrt( self.map {|v| v**2}.mean )
end

#sdObject

Save as R’s sd, i.e. uses N-1 in denominator.



81
82
83
# File 'lib/feldtruby/array/basic_stats.rb', line 81

def sd
  Math.sqrt( self.var )
end

#stdevObject



70
71
72
# File 'lib/feldtruby/array/basic_stats.rb', line 70

def stdev
  Math.sqrt( self.variance )
end

#sumObject



2
3
4
# File 'lib/feldtruby/array/basic_stats.rb', line 2

def sum
  self.inject(0) {|s, e| s+e}
end

#sum_of_absObject



120
121
122
123
124
# File 'lib/feldtruby/array/basic_stats.rb', line 120

def sum_of_abs
  sum = 0.0
  self.each {|v| sum += v.abs}
  sum
end

#sum_of_abs_deviations(fromValue = 0.0) ⇒ Object



114
115
116
117
118
# File 'lib/feldtruby/array/basic_stats.rb', line 114

def sum_of_abs_deviations(fromValue = 0.0)
  sum = 0.0
  self.each {|v| sum += (v-fromValue).abs}
  sum
end

#sum_squared_error(b) ⇒ Object



126
127
128
129
130
# File 'lib/feldtruby/array/basic_stats.rb', line 126

def sum_squared_error(b)
  sum = 0.0
  self.each_with_index {|e,i| d = e-b[i]; sum += d*d}
  sum
end

#summary_statsObject

Return summary stats for an array of numbers.



138
139
140
141
142
# File 'lib/feldtruby/array/basic_stats.rb', line 138

def summary_stats
return "" if length == 0
vals = [mean, self.min, self.max, median, stdev]
  "%.3g (min = %.3g, max = %.3g, median = %.3g, stdev = %.3g)" % vals
end

#varObject

Same as R’s var, i.e. uses N-1 in denominator.



75
76
77
78
# File 'lib/feldtruby/array/basic_stats.rb', line 75

def var
  n = self.length.to_f
  (variance * n) / (n-1)
end

#varianceObject



64
65
66
67
68
# File 'lib/feldtruby/array/basic_stats.rb', line 64

def variance
  return 0 if self.length == 0
  avg = self.mean
  self.map {|e| (e-avg)**2}.sum / self.length.to_f
end

#weighted_mean(weights = nil) ⇒ Object

Weighted mean of elements



106
107
108
109
110
111
112
# File 'lib/feldtruby/array/basic_stats.rb', line 106

def weighted_mean(weights = nil)
  if weights
    self.weighted_sum(weights) / weights.sum.to_f
  else
    self.mean
  end
end

#weighted_sum(weights = nil) ⇒ Object

Weighted sum of elements



96
97
98
99
100
101
102
103
# File 'lib/feldtruby/array/basic_stats.rb', line 96

def weighted_sum(weights = nil)
  if weights
    raise "Not same num of weights (#{weights.length}) as num of elements (#{self.length})" if self.length != weights.length
    self.zip(weights).map {|e,w| e*w}.sum
  else
    self.sum
  end
end