statsample 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. data.tar.gz.sig +1 -2
  2. data/History.txt +9 -0
  3. data/Manifest.txt +6 -2
  4. data/README.txt +6 -3
  5. data/Rakefile +4 -19
  6. data/examples/dominance_analysis.rb +0 -1
  7. data/examples/parallel_analysis.rb +2 -1
  8. data/examples/parallel_analysis_tetrachoric.rb +1 -1
  9. data/examples/reliability.rb +12 -0
  10. data/lib/statsample.rb +1 -2
  11. data/lib/statsample/anova.rb +9 -151
  12. data/lib/statsample/anova/oneway.rb +151 -0
  13. data/lib/statsample/anova/twoway.rb +211 -0
  14. data/lib/statsample/bivariate.rb +1 -0
  15. data/lib/statsample/dataset.rb +15 -1
  16. data/lib/statsample/dominanceanalysis.rb +10 -13
  17. data/lib/statsample/factor/parallelanalysis.rb +4 -2
  18. data/lib/statsample/multiset.rb +6 -0
  19. data/lib/statsample/regression/multiple/baseengine.rb +1 -1
  20. data/lib/statsample/reliability.rb +32 -5
  21. data/lib/statsample/vector.rb +6 -5
  22. data/test/{test_helpers.rb → helpers_tests.rb} +2 -0
  23. data/test/test_anovaoneway.rb +1 -2
  24. data/test/test_anovatwoway.rb +38 -0
  25. data/test/test_anovatwowaywithdataset.rb +49 -0
  26. data/test/test_anovawithvectors.rb +1 -1
  27. data/test/test_bivariate.rb +1 -1
  28. data/test/test_bivariate_polychoric.rb +1 -1
  29. data/test/test_codification.rb +1 -1
  30. data/test/test_combination.rb +1 -1
  31. data/test/test_crosstab.rb +1 -1
  32. data/test/test_csv.rb +1 -1
  33. data/test/test_dataset.rb +8 -1
  34. data/test/test_distribution.rb +1 -1
  35. data/test/test_dominance_analysis.rb +2 -1
  36. data/test/test_factor.rb +1 -1
  37. data/test/test_ggobi.rb +1 -1
  38. data/test/test_gsl.rb +1 -1
  39. data/test/test_histogram.rb +1 -1
  40. data/test/test_logit.rb +1 -1
  41. data/test/test_matrix.rb +1 -1
  42. data/test/test_mle.rb +1 -1
  43. data/test/test_multiset.rb +1 -1
  44. data/test/test_permutation.rb +1 -1
  45. data/test/test_regression.rb +3 -4
  46. data/test/test_reliability.rb +15 -2
  47. data/test/test_resample.rb +1 -1
  48. data/test/test_srs.rb +1 -1
  49. data/test/test_statistics.rb +1 -1
  50. data/test/test_stest.rb +1 -1
  51. data/test/test_stratified.rb +1 -1
  52. data/test/test_svg_graph.rb +1 -1
  53. data/test/test_test_f.rb +1 -1
  54. data/test/test_test_t.rb +1 -1
  55. data/test/test_umannwhitney.rb +1 -1
  56. data/test/test_vector.rb +1 -1
  57. data/test/test_xls.rb +1 -1
  58. metadata +92 -40
  59. metadata.gz.sig +0 -0
  60. data/lib/statistics2.rb +0 -531
data.tar.gz.sig CHANGED
@@ -1,2 +1 @@
1
- �$ ADJ��)���r�,aC�qa8<�yo���RTX�fO� �9��B�f��<�/�oCA���A�~�F�F��,rډ��#��w���Gy*�^|}�����CU��*B��Y A�@���gD�
2
- `��O�c�>һ��|�c�+���}�I�ʸi�! ��fSW���]Q���#c�ۦ�+ȋ�M� l;xw{^6 �q%"ry> �8��O�)�)h0�CU����؃ʺ]H��ϞN�<����
1
+ �����%y�ӵ���T���:�lbt ��郧�%t���§�An�?2��JRw��ov��t[a 4�Ӏ%�_iN
data/History.txt CHANGED
@@ -1,3 +1,12 @@
1
+ === 0.11.0 / 2010-04-16
2
+ <b>New features:</b>
3
+ * Added Statsample::Anova::TwoWay and Statsample::Anova::TwoWayWithVectors
4
+ * Added Statsample.clone_only valid and Statsample::Dataset.clone_only_valid, for cheap copy on already clean vectors
5
+ <b>Optimizations and bug fix</b>
6
+ * Removed library statistics2 from package. Used gem statistics2 instead, because have a extension version
7
+ * Added example for Reliability class
8
+ * Bug fix on Statsample::DominanceAnalysis
9
+
1
10
  === 0.10.0 / 2010-04-13
2
11
 
3
12
  <b>API modifications</b>
data/Manifest.txt CHANGED
@@ -21,6 +21,7 @@ examples/parallel_analysis.rb
21
21
  examples/parallel_analysis_tetrachoric.rb
22
22
  examples/polychoric.rb
23
23
  examples/principal_axis.rb
24
+ examples/reliability.rb
24
25
  examples/t_test.rb
25
26
  examples/tetrachoric.rb
26
27
  examples/vector.rb
@@ -31,9 +32,10 @@ lib/distribution/normal.rb
31
32
  lib/distribution/normalbivariate.rb
32
33
  lib/distribution/t.rb
33
34
  lib/spss.rb
34
- lib/statistics2.rb
35
35
  lib/statsample.rb
36
36
  lib/statsample/anova.rb
37
+ lib/statsample/anova/oneway.rb
38
+ lib/statsample/anova/twoway.rb
37
39
  lib/statsample/bivariate.rb
38
40
  lib/statsample/bivariate/polychoric.rb
39
41
  lib/statsample/bivariate/tetrachoric.rb
@@ -89,7 +91,10 @@ po/es/statsample.mo
89
91
  po/es/statsample.po
90
92
  po/statsample.pot
91
93
  setup.rb
94
+ test/helpers_tests.rb
92
95
  test/test_anovaoneway.rb
96
+ test/test_anovatwoway.rb
97
+ test/test_anovatwowaywithdataset.rb
93
98
  test/test_anovawithvectors.rb
94
99
  test/test_bivariate.rb
95
100
  test/test_bivariate_polychoric.rb
@@ -104,7 +109,6 @@ test/test_dominance_analysis.rb
104
109
  test/test_factor.rb
105
110
  test/test_ggobi.rb
106
111
  test/test_gsl.rb
107
- test/test_helpers.rb
108
112
  test/test_histogram.rb
109
113
  test/test_logit.rb
110
114
  test/test_matrix.rb
data/README.txt CHANGED
@@ -100,9 +100,12 @@ Optional:
100
100
 
101
101
  <b>Note</b>: Use gsl 1.12.109 or later.
102
102
 
103
- == DOWNLOAD
104
- * Gems and bugs report: http://rubyforge.org/projects/ruby-statsample/
105
- * SVN and Wiki: http://code.google.com/p/ruby-statsample/
103
+ == RESOURCES
104
+
105
+ * Source code on github: http://github.com/clbustos/statsample
106
+ * API: http://ruby-statsample.rubyforge.org/statsample/
107
+ * Bug report and feature request: http://code.google.com/p/ruby-statsample/issues/list
108
+
106
109
 
107
110
  == INSTALL:
108
111
 
data/Rakefile CHANGED
@@ -1,18 +1,12 @@
1
1
  #!/usr/bin/ruby
2
2
  # -*- ruby -*-
3
3
  # -*- coding: utf-8 -*-
4
+ $:.unshift(File.dirname(__FILE__)+'/lib/')
4
5
 
5
6
  require 'rubygems'
6
7
  require 'hoe'
7
8
  require './lib/statsample'
8
-
9
-
10
-
11
-
12
-
13
- if File.exists? './local_rakefile.rb'
14
- require './local_rakefile'
15
- end
9
+ Hoe.plugin :git
16
10
 
17
11
  desc "Ruby Lint"
18
12
  task :lint do
@@ -40,10 +34,10 @@ end
40
34
 
41
35
  h=Hoe.spec('statsample') do
42
36
  self.version=Statsample::VERSION
43
- self.testlib=:minitest
37
+ #self.testlib=:minitest
44
38
  self.rubyforge_name = "ruby-statsample"
45
39
  self.developer('Claudio Bustos', 'clbustos@gmail.com')
46
- self.extra_deps << ["spreadsheet","~>0.6.0"] << ["svg-graph", "~>1.0"] << ["reportbuilder", "~>1.0"] << ["minimization", "~>0.2.0"] << ["fastercsv"] << ["dirty-memoize", "~>0.0"]
40
+ self.extra_deps << ["spreadsheet","~>0.6.0"] << ["svg-graph", "~>1.0"] << ["reportbuilder", "~>1.0"] << ["minimization", "~>0.2.0"] << ["fastercsv"] << ["dirty-memoize", "~>0.0"] << ["statistics2", "~>0.54"]
47
41
  self.clean_globs << "test/images/*" << "demo/item_analysis/*" << "demo/Regression"
48
42
  self.need_rdoc=false
49
43
  end
@@ -88,13 +82,4 @@ task :publicar_docs => [:clean, :docs] do
88
82
  }
89
83
  sh %{rsync #{h.rsync_args} #{local_dir}/ #{host}:#{remote_dir}}
90
84
  end
91
-
92
- task :release => [:tag] do
93
- end
94
-
95
- task :tag do
96
- sh %(svn commit -m "Version bump: #{Statsample::VERSION}")
97
- sh %(svn cp https://ruby-statsample.googlecode.com/svn/reportbuilder/trunk https://ruby-statsample.googlecode.com/svn/statsample/tags/v#{Statsample::VERSION} -m "ReportBuilder #{Statsample::VERSION} tagged")
98
- end
99
-
100
85
  # vim: syntax=Ruby
@@ -25,4 +25,3 @@ rb.add(da)
25
25
 
26
26
 
27
27
  puts rb.to_text
28
- rb.save_rtf("dominance_analysis.rtf")
@@ -4,6 +4,7 @@ $:.unshift(File.dirname(__FILE__)+'/../lib/')
4
4
  require 'statsample'
5
5
  samples=100
6
6
  variables=30
7
+ iterations=50
7
8
  rng = GSL::Rng.alloc()
8
9
  f1=samples.times.collect {rng.ugaussian()}.to_scale
9
10
  f2=samples.times.collect {rng.ugaussian()}.to_scale
@@ -16,7 +17,7 @@ variables.times do |i|
16
17
  end
17
18
  ds=vectors.to_dataset
18
19
 
19
- pa=Statsample::Factor::ParallelAnalysis.new(ds, :iterations=>10, :debug=>true)
20
+ pa=Statsample::Factor::ParallelAnalysis.new(ds, :iterations=>iterations, :debug=>true)
20
21
  pca=Statsample::Factor::PCA.new(Statsample::Bivariate.correlation_matrix(ds))
21
22
  rb=ReportBuilder.new(:name=>"Parallel Analysis with simulation") do |g|
22
23
  g.text("There are 3 real factors on data")
@@ -3,7 +3,7 @@ $:.unshift(File.dirname(__FILE__)+'/../lib/')
3
3
 
4
4
  require 'statsample'
5
5
  samples=1000
6
- variables=30
6
+ variables=10
7
7
  rng = GSL::Rng.alloc()
8
8
  f1=samples.times.collect {rng.ugaussian()}.to_scale
9
9
  f2=samples.times.collect {rng.ugaussian()}.to_scale
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/ruby
2
+ $:.unshift(File.dirname(__FILE__)+'/../lib')
3
+ require 'statsample'
4
+ samples=100
5
+ a=samples.times.map {rand(100)}.to_scale
6
+ ds=Statsample::Dataset.new
7
+ 20.times do |i|
8
+ ds["v#{i}"]=a.collect {|v| v+rand(20)}.to_scale
9
+ end
10
+ ds.update_valid_data
11
+ rel=Statsample::Reliability::ItemAnalysis.new(ds)
12
+ puts rel.summary
data/lib/statsample.rb CHANGED
@@ -22,7 +22,6 @@
22
22
  require 'matrix'
23
23
  require 'distribution'
24
24
  require 'dirty-memoize'
25
- gem 'reportbuilder','~>1.0'
26
25
  require 'reportbuilder'
27
26
  class Numeric
28
27
  def square ; self * self ; end
@@ -112,7 +111,7 @@ module Statsample
112
111
  false
113
112
  end
114
113
  end
115
- VERSION = '0.10.0'
114
+ VERSION = '0.11.0'
116
115
  SPLIT_TOKEN = ","
117
116
  autoload(:Database, 'statsample/converters')
118
117
  autoload(:Anova, 'statsample/anova')
@@ -4,161 +4,19 @@ module Statsample
4
4
  def oneway(*args)
5
5
  OneWay.new(*args)
6
6
  end
7
+ def twoway(*args)
8
+ TwoWay.new(*args)
9
+ end
10
+
7
11
  def oneway_with_vectors(*args)
8
12
  OneWayWithVectors.new(*args)
9
13
  end
10
- end
11
- # = Generic Anova one-way.
12
- # You could enter the sum of squares or the mean squares. You
13
- # should enter the degrees of freedom for numerator and denominator.
14
- # == Usage
15
- # anova=Statsample::Anova::OneWay(:ss_num=>10,:ss_den=>20, :df_num=>2, :df_den=>10, @name=>"ANOVA for....")
16
- class OneWay
17
- include GetText
18
- bindtextdomain("statsample")
19
- attr_reader :df_num, :df_den, :ss_num, :ss_den, :ms_num, :ms_den, :ms_total, :df_total, :ss_total
20
- # Name of ANOVA Analisys
21
- attr_accessor :name
22
- attr_accessor :name_denominator
23
- attr_accessor :name_numerator
24
- def initialize(opts=Hash.new)
25
- # First see if sum of squares or mean squares are entered
26
- raise ArgumentError, "You should set d.f." unless (opts.has_key? :df_num and opts.has_key? :df_den)
27
- @df_num=opts.delete :df_num
28
- @df_den=opts.delete :df_den
29
- @df_total=@df_num+@df_den
30
- if(opts.has_key? :ss_num and opts.has_key? :ss_den)
31
- @ss_num = opts.delete :ss_num
32
- @ss_den =opts.delete :ss_den
33
- @ms_num =@ss_num.quo(@df_num)
34
- @ms_den =@ss_den.quo(@df_den)
35
- elsif (opts.has_key? :ms_num and opts.has_key? :ms_den)
36
- @ms_num =opts.delete :ms_num
37
- @ms_den =opts.delete :ms_den
38
- @ss_num =@ms_num * @df_num
39
- @ss_den =@ss_den * @df_den
40
- end
41
- @ss_total=@ss_num+@ss_den
42
- @ms_total=@ms_num+@ms_den
43
- opts_default={:name=>"ANOVA",
44
- :name_denominator=>"Explained variance",
45
- :name_numerator=>"Unexplained variance"}
46
- @opts=opts_default.merge(opts)
47
- opts_default.keys.each {|k|
48
- send("#{k}=", @opts[k])
49
- }
50
- @f_object=Statsample::Test::F.new(@ms_num,@ms_den,@df_num,@df_den)
51
- end
52
- # F value
53
- def f
54
- @f_object.f
55
- end
56
- # P-value of F test
57
- def probability
58
- @f_object.probability
59
- end
60
- # Summary of Anova analysis
61
- def summary
62
- ReportBuilder.new(:no_title=>true).add(self).to_text
63
- end
64
- def report_building(builder) #:nodoc:
65
- builder.section(:name=>@name) do |b|
66
- report_building_table(b)
67
- end
68
- end
69
- def report_building_table(builder) #:nodoc:
70
- builder.table(:name=>_("%s Table") % @name, :header=>%w{source ss df ms f p}.map {|v| _(v)}) do |t|
71
- t.row([@name_numerator, sprintf("%0.3f",@ss_num), @df_num, sprintf("%0.3f",@ms_num), sprintf("%0.3f",f), sprintf("%0.3f", probability)])
72
- t.row([@name_denominator, sprintf("%0.3f",@ss_den), @df_den, sprintf("%0.3f",@ms_den), "", ""])
73
- t.row([_("Total"), sprintf("%0.3f",@ss_total), @df_total, sprintf("%0.3f",@ms_total),"",""])
74
- end
75
- end
76
-
77
- end
78
- # One Way Anova with vectors
79
- # Example:
80
- # v1=[2,3,4,5,6].to_scale
81
- # v2=[3,3,4,5,6].to_scale
82
- # v3=[5,3,1,5,6].to_scale
83
- # anova=Statsample::Anova::OneWayWithVectors.new([v1,v2,v3])
84
- # anova.f
85
- # => 0.0243902439024391
86
- # anova.probability
87
- # => 0.975953044203438
88
- # anova.sst
89
- # => 32.9333333333333
90
- #
91
- class OneWayWithVectors < OneWay
92
- # Show on summary Levene test
93
- attr_accessor :summary_levene
94
- # Show on summary descriptives for vectors
95
- attr_accessor :summary_descriptives
96
- def initialize(*args)
97
- if args[0].is_a? Array
98
- @vectors=args.shift
99
- else
100
- @vectors=args.find_all {|v| v.is_a? Statsample::Vector}
101
- opts=args.find {|v| v.is_a? Hash}
102
- end
103
- opts||=Hash.new
104
- opts_default={:name=>_("Anova One-Way"),
105
- :name_numerator=>"Between Groups",
106
- :name_denominator=>"Within Groups",
107
- :summary_descriptives=>false,
108
- :summary_levene=>false}
109
- @opts=opts_default.merge(opts).merge(:ss_num=>ssbg, :ss_den=>sswg, :df_num=>df_bg, :df_den=>df_wg)
110
- super(@opts)
111
- end
112
- alias :sst :ss_total
113
- def levene
114
- Statsample::Test.levene(@vectors, :name=>_("Test of Homogeneity of variances (Levene)"))
115
- end
116
- # Total mean
117
- def total_mean
118
- sum=@vectors.inject(0){|a,v| a+v.sum}
119
- sum.quo(n)
120
- end
121
- # Sum of squares within groups
122
- def sswg
123
- @sswg||=@vectors.inject(0) {|total,vector| total+vector.ss }
124
- end
125
- # Sum of squares between groups
126
- def ssbg
127
- m=total_mean
128
- @vectors.inject(0) do |total,vector|
129
- total + (vector.mean-m).square * vector.size
130
- end
131
- end
132
- # Degrees of freedom within groups
133
- def df_wg
134
- @dk_wg||=n-k
135
- end
136
- def k
137
- @k||=@vectors.size
138
- end
139
- # Degrees of freedom between groups
140
- def df_bg
141
- k-1
142
- end
143
- # Total number of cases
144
- def n
145
- @vectors.inject(0){|a,v| a+v.size}
146
- end
147
- def report_building(builder) # :nodoc:
148
- builder.section(:name=>@name) do |s|
149
- if summary_descriptives
150
- s.table(:name=>_("Descriptives"),:header=>%w{Name N Mean SD Min Max}.map {|v| _(v)}) do |t|
151
- @vectors.each do |v|
152
- t.row [v.name, v.n_valid, "%0.4f" % v.mean, "%0.4f" % v.sd, "%0.4f" % v.min, "%0.4f" % v.max]
153
- end
154
- end
155
- end
156
- if summary_levene
157
- s.parse_element(levene)
158
- end
159
- report_building_table(s)
160
- end
14
+ def twoway_with_vectors(*args)
15
+ TwoWayWithVectors.new(*args)
161
16
  end
17
+
162
18
  end
163
19
  end
164
20
  end
21
+ require 'statsample/anova/oneway'
22
+ require 'statsample/anova/twoway'
@@ -0,0 +1,151 @@
1
+ module Statsample
2
+ module Anova
3
+ # = Generic Anova one-way.
4
+ # You could enter the sum of squares or the mean squares. You
5
+ # should enter the degrees of freedom for numerator and denominator.
6
+ # == Usage
7
+ # anova=Statsample::Anova::OneWay(:ss_num=>10,:ss_den=>20, :df_num=>2, :df_den=>10, @name=>"ANOVA for....")
8
+ class OneWay
9
+ include Summarizable
10
+ attr_reader :df_num, :df_den, :ss_num, :ss_den, :ms_num, :ms_den, :ms_total, :df_total, :ss_total
11
+ # Name of ANOVA Analisys
12
+ attr_accessor :name
13
+ attr_accessor :name_denominator
14
+ attr_accessor :name_numerator
15
+ def initialize(opts=Hash.new)
16
+ # First see if sum of squares or mean squares are entered
17
+ raise ArgumentError, "You should set d.f." unless (opts.has_key? :df_num and opts.has_key? :df_den)
18
+ @df_num=opts.delete :df_num
19
+ @df_den=opts.delete :df_den
20
+ @df_total=@df_num+@df_den
21
+ if(opts.has_key? :ss_num and opts.has_key? :ss_den)
22
+ @ss_num = opts.delete :ss_num
23
+ @ss_den =opts.delete :ss_den
24
+ @ms_num =@ss_num.quo(@df_num)
25
+ @ms_den =@ss_den.quo(@df_den)
26
+ elsif (opts.has_key? :ms_num and opts.has_key? :ms_den)
27
+ @ms_num =opts.delete :ms_num
28
+ @ms_den =opts.delete :ms_den
29
+ @ss_num =@ms_num * @df_num
30
+ @ss_den =@ss_den * @df_den
31
+ end
32
+ @ss_total=@ss_num+@ss_den
33
+ @ms_total=@ms_num+@ms_den
34
+ opts_default={:name=>"ANOVA",
35
+ :name_denominator=>"Explained variance",
36
+ :name_numerator=>"Unexplained variance"}
37
+ @opts=opts_default.merge(opts)
38
+ opts_default.keys.each {|k|
39
+ send("#{k}=", @opts[k])
40
+ }
41
+ @f_object=Statsample::Test::F.new(@ms_num,@ms_den,@df_num,@df_den)
42
+ end
43
+ # F value
44
+ def f
45
+ @f_object.f
46
+ end
47
+ # P-value of F test
48
+ def probability
49
+ @f_object.probability
50
+ end
51
+ def report_building(builder) #:nodoc:
52
+ builder.section(:name=>@name) do |b|
53
+ report_building_table(b)
54
+ end
55
+ end
56
+ def report_building_table(builder) #:nodoc:
57
+ builder.table(:name=>_("%s Table") % @name, :header=>%w{source ss df ms f p}.map {|v| _(v)}) do |t|
58
+ t.row([@name_numerator, sprintf("%0.3f",@ss_num), @df_num, sprintf("%0.3f",@ms_num), sprintf("%0.3f",f), sprintf("%0.3f", probability)])
59
+ t.row([@name_denominator, sprintf("%0.3f",@ss_den), @df_den, sprintf("%0.3f",@ms_den), "", ""])
60
+ t.row([_("Total"), sprintf("%0.3f",@ss_total), @df_total, sprintf("%0.3f",@ms_total),"",""])
61
+ end
62
+ end
63
+
64
+ end
65
+ # One Way Anova with vectors
66
+ # Example:
67
+ # v1=[2,3,4,5,6].to_scale
68
+ # v2=[3,3,4,5,6].to_scale
69
+ # v3=[5,3,1,5,6].to_scale
70
+ # anova=Statsample::Anova::OneWayWithVectors.new([v1,v2,v3])
71
+ # anova.f
72
+ # => 0.0243902439024391
73
+ # anova.probability
74
+ # => 0.975953044203438
75
+ # anova.sst
76
+ # => 32.9333333333333
77
+ #
78
+ class OneWayWithVectors < OneWay
79
+ # Show on summary Levene test
80
+ attr_accessor :summary_levene
81
+ # Show on summary descriptives for vectors
82
+ attr_accessor :summary_descriptives
83
+ def initialize(*args)
84
+ if args[0].is_a? Array
85
+ @vectors=args.shift
86
+ else
87
+ @vectors=args.find_all {|v| v.is_a? Statsample::Vector}
88
+ opts=args.find {|v| v.is_a? Hash}
89
+ end
90
+ opts||=Hash.new
91
+ opts_default={:name=>_("Anova One-Way"),
92
+ :name_numerator=>"Between Groups",
93
+ :name_denominator=>"Within Groups",
94
+ :summary_descriptives=>false,
95
+ :summary_levene=>false}
96
+ @opts=opts_default.merge(opts).merge(:ss_num=>ssbg, :ss_den=>sswg, :df_num=>df_bg, :df_den=>df_wg)
97
+ super(@opts)
98
+ end
99
+ alias :sst :ss_total
100
+ def levene
101
+ Statsample::Test.levene(@vectors, :name=>_("Test of Homogeneity of variances (Levene)"))
102
+ end
103
+ # Total mean
104
+ def total_mean
105
+ sum=@vectors.inject(0){|a,v| a+v.sum}
106
+ sum.quo(n)
107
+ end
108
+ # Sum of squares within groups
109
+ def sswg
110
+ @sswg||=@vectors.inject(0) {|total,vector| total+vector.ss }
111
+ end
112
+ # Sum of squares between groups
113
+ def ssbg
114
+ m=total_mean
115
+ @vectors.inject(0) do |total,vector|
116
+ total + (vector.mean-m).square * vector.size
117
+ end
118
+ end
119
+ # Degrees of freedom within groups
120
+ def df_wg
121
+ @dk_wg||=n-k
122
+ end
123
+ def k
124
+ @k||=@vectors.size
125
+ end
126
+ # Degrees of freedom between groups
127
+ def df_bg
128
+ k-1
129
+ end
130
+ # Total number of cases
131
+ def n
132
+ @vectors.inject(0){|a,v| a+v.size}
133
+ end
134
+ def report_building(builder) # :nodoc:
135
+ builder.section(:name=>@name) do |s|
136
+ if summary_descriptives
137
+ s.table(:name=>_("Descriptives"),:header=>%w{Name N Mean SD Min Max}.map {|v| _(v)}) do |t|
138
+ @vectors.each do |v|
139
+ t.row [v.name, v.n_valid, "%0.4f" % v.mean, "%0.4f" % v.sd, "%0.4f" % v.min, "%0.4f" % v.max]
140
+ end
141
+ end
142
+ end
143
+ if summary_levene
144
+ s.parse_element(levene)
145
+ end
146
+ report_building_table(s)
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end