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