Class: Crosstab::Cell
- Inherits:
-
Object
- Object
- Crosstab::Cell
- Defined in:
- lib/crosstab/cell.rb
Instance Method Summary collapse
-
#base(value = nil) ⇒ Object
DSL accessor for the base attribute.
-
#column(value = nil) ⇒ Object
DSL accessor for the column that this cell belongs to.
-
#frequency(value = nil) ⇒ Object
Returns and sets the frequency for this cell, that is, the number of records that meet both the row and column qualifications.
-
#initialize(options = {}) ⇒ Cell
constructor
Optionally, can take options :base and :frequency for a fast initialization.
-
#percentage ⇒ Object
Returns the frequency divided by the base.
-
#result ⇒ Object
Returns an array of default stats (frequency, percentage, then sigtesting).
-
#significant_against?(test_cell, level = 0.95) ⇒ Boolean
Tests this cell against another and returns true if it is statistically significant.
Constructor Details
#initialize(options = {}) ⇒ Cell
16 17 18 19 |
# File 'lib/crosstab/cell.rb', line 16 def initialize(={}) base [:base] if [:base] frequency [:frequency] if [:frequency] end |
Instance Method Details
#base(value = nil) ⇒ Object
DSL accessor for the base attribute. The base is the number of records used in calculations for this cell.
Example:
cell = Crosstab::Cell.new
cell.frequency 2
cell.base 4
cell.percentage
# => 0.5
33 34 35 36 37 38 39 |
# File 'lib/crosstab/cell.rb', line 33 def base(value=nil) if value @base = value else @base ||= 0 end end |
#column(value = nil) ⇒ Object
155 156 157 158 159 160 161 |
# File 'lib/crosstab/cell.rb', line 155 def column(value=nil) if value @column = value else @column ||= nil end end |
#frequency(value = nil) ⇒ Object
Returns and sets the frequency for this cell, that is, the number of records that meet both the row and column qualifications.
Example:
cell = Crosstab::Cell.new
cell.frequency 2
cell.base 4
cell.percentage
# => 0.5
53 54 55 56 57 58 59 |
# File 'lib/crosstab/cell.rb', line 53 def frequency(value=nil) if value @frequency = value else @frequency ||= 0 end end |
#percentage ⇒ Object
Returns the frequency divided by the base. Always a float.
Example:
cell = Crosstab::Cell.new
cell.frequency 2
cell.base 4
cell.percentage
# => 0.5
73 74 75 76 77 78 79 |
# File 'lib/crosstab/cell.rb', line 73 def percentage if base > 0 frequency.to_f / base.to_f else 0.0 end end |
#result ⇒ Object
Returns an array of default stats (frequency, percentage, then sigtesting). It’s only really useful for printing within reports. If the frequency of the cell is 0, it returns [ “–” ] because what’s the point of displaying 0, 0%?
Example:
cell = Crosstab::Cell.new
cell.frequency 2
cell.base 4
cell.result
# => [2, 0.5]
95 96 97 98 99 100 101 |
# File 'lib/crosstab/cell.rb', line 95 def result if frequency > 0 [frequency, "#{(percentage * 100).round}%" ] else ["--"] end end |
#significant_against?(test_cell, level = 0.95) ⇒ Boolean
Tests this cell against another and returns true if it is statistically significant. The default testing level is 95%, represented as a float (i.e., 0.95.) Other levels supported are 0.85, 0.90, and 0.98.
Example:
cell1 = Crosstab::Cell.new :base => 100, :frequency => 65
cell2 = Crosstab::Cell.new :base => 100, :frequency => 50
cell1.significant_against? cell2
# => true
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/crosstab/cell.rb', line 114 def significant_against?(test_cell, level=0.95) zfactor = { 0.98 => 2.327, 0.95 => 1.960, 0.90 => 1.645, 0.85 => 1.440 } # From what I understand, a z-test is meaningless if either of the two cells are in the bottom or top 10%. # So we return false. If you're any good at statistics, I would love to hear your opinion on this. # I've done this shit for ten years and I'm still copying formulas out of books. Frankly, it sounds odd, # and I can't seem to find any good documentation on why it is that we do it this way. 10% sounds like a fucking guess. return false unless [self, test_cell].all? { |x| (0.10..0.90).include? x.percentage } # The preperation a = self.percentage * self.base + test_cell.percentage * test_cell.base b = self.base + test_cell.base c = 1.0 / self.base + 1.0 / test_cell.base # The main calculation z = (self.percentage - test_cell.percentage) / Math.sqrt(a / b * (1 - a / b) * c) # The test z >= zfactor[level] end |