statsample-ekatena 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (156) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.travis.yml +23 -0
  4. data/CONTRIBUTING.md +17 -0
  5. data/Gemfile +2 -0
  6. data/History.txt +457 -0
  7. data/LICENSE.txt +12 -0
  8. data/README.md +175 -0
  9. data/Rakefile +44 -0
  10. data/benchmarks/correlation_matrix_15_variables.rb +32 -0
  11. data/benchmarks/correlation_matrix_5_variables.rb +33 -0
  12. data/benchmarks/correlation_matrix_methods/correlation_matrix.ds +0 -0
  13. data/benchmarks/correlation_matrix_methods/correlation_matrix.html +93 -0
  14. data/benchmarks/correlation_matrix_methods/correlation_matrix.rb +71 -0
  15. data/benchmarks/correlation_matrix_methods/correlation_matrix.xls +0 -0
  16. data/benchmarks/correlation_matrix_methods/correlation_matrix_gsl_ruby.ods +0 -0
  17. data/benchmarks/correlation_matrix_methods/correlation_matrix_with_graphics.ods +0 -0
  18. data/benchmarks/correlation_matrix_methods/results.ds +0 -0
  19. data/benchmarks/factor_map.rb +37 -0
  20. data/benchmarks/helpers_benchmark.rb +5 -0
  21. data/data/locale/es/LC_MESSAGES/statsample.mo +0 -0
  22. data/doc_latex/manual/equations.tex +78 -0
  23. data/examples/boxplot.rb +28 -0
  24. data/examples/chisquare_test.rb +23 -0
  25. data/examples/correlation_matrix.rb +32 -0
  26. data/examples/dataset.rb +30 -0
  27. data/examples/dominance_analysis.rb +33 -0
  28. data/examples/dominance_analysis_bootstrap.rb +32 -0
  29. data/examples/histogram.rb +26 -0
  30. data/examples/icc.rb +24 -0
  31. data/examples/levene.rb +29 -0
  32. data/examples/multiple_regression.rb +20 -0
  33. data/examples/multivariate_correlation.rb +33 -0
  34. data/examples/parallel_analysis.rb +40 -0
  35. data/examples/polychoric.rb +40 -0
  36. data/examples/principal_axis.rb +26 -0
  37. data/examples/reliability.rb +31 -0
  38. data/examples/scatterplot.rb +25 -0
  39. data/examples/t_test.rb +27 -0
  40. data/examples/tetrachoric.rb +17 -0
  41. data/examples/u_test.rb +24 -0
  42. data/examples/vector.rb +20 -0
  43. data/examples/velicer_map_test.rb +46 -0
  44. data/grab_references.rb +29 -0
  45. data/lib/spss.rb +134 -0
  46. data/lib/statsample-ekatena/analysis.rb +100 -0
  47. data/lib/statsample-ekatena/analysis/suite.rb +89 -0
  48. data/lib/statsample-ekatena/analysis/suitereportbuilder.rb +44 -0
  49. data/lib/statsample-ekatena/anova.rb +24 -0
  50. data/lib/statsample-ekatena/anova/contrast.rb +79 -0
  51. data/lib/statsample-ekatena/anova/oneway.rb +187 -0
  52. data/lib/statsample-ekatena/anova/twoway.rb +207 -0
  53. data/lib/statsample-ekatena/bivariate.rb +406 -0
  54. data/lib/statsample-ekatena/bivariate/pearson.rb +54 -0
  55. data/lib/statsample-ekatena/codification.rb +182 -0
  56. data/lib/statsample-ekatena/converter/csv.rb +28 -0
  57. data/lib/statsample-ekatena/converter/spss.rb +48 -0
  58. data/lib/statsample-ekatena/converters.rb +211 -0
  59. data/lib/statsample-ekatena/crosstab.rb +188 -0
  60. data/lib/statsample-ekatena/daru.rb +115 -0
  61. data/lib/statsample-ekatena/dataset.rb +10 -0
  62. data/lib/statsample-ekatena/dominanceanalysis.rb +425 -0
  63. data/lib/statsample-ekatena/dominanceanalysis/bootstrap.rb +232 -0
  64. data/lib/statsample-ekatena/factor.rb +104 -0
  65. data/lib/statsample-ekatena/factor/map.rb +124 -0
  66. data/lib/statsample-ekatena/factor/parallelanalysis.rb +166 -0
  67. data/lib/statsample-ekatena/factor/pca.rb +242 -0
  68. data/lib/statsample-ekatena/factor/principalaxis.rb +243 -0
  69. data/lib/statsample-ekatena/factor/rotation.rb +198 -0
  70. data/lib/statsample-ekatena/formula/fit_model.rb +46 -0
  71. data/lib/statsample-ekatena/formula/formula.rb +306 -0
  72. data/lib/statsample-ekatena/graph.rb +11 -0
  73. data/lib/statsample-ekatena/graph/boxplot.rb +236 -0
  74. data/lib/statsample-ekatena/graph/histogram.rb +198 -0
  75. data/lib/statsample-ekatena/graph/scatterplot.rb +213 -0
  76. data/lib/statsample-ekatena/histogram.rb +180 -0
  77. data/lib/statsample-ekatena/matrix.rb +329 -0
  78. data/lib/statsample-ekatena/multiset.rb +310 -0
  79. data/lib/statsample-ekatena/regression.rb +65 -0
  80. data/lib/statsample-ekatena/regression/multiple.rb +89 -0
  81. data/lib/statsample-ekatena/regression/multiple/alglibengine.rb +128 -0
  82. data/lib/statsample-ekatena/regression/multiple/baseengine.rb +251 -0
  83. data/lib/statsample-ekatena/regression/multiple/gslengine.rb +129 -0
  84. data/lib/statsample-ekatena/regression/multiple/matrixengine.rb +205 -0
  85. data/lib/statsample-ekatena/regression/multiple/rubyengine.rb +86 -0
  86. data/lib/statsample-ekatena/regression/simple.rb +121 -0
  87. data/lib/statsample-ekatena/reliability.rb +150 -0
  88. data/lib/statsample-ekatena/reliability/icc.rb +415 -0
  89. data/lib/statsample-ekatena/reliability/multiscaleanalysis.rb +181 -0
  90. data/lib/statsample-ekatena/reliability/scaleanalysis.rb +233 -0
  91. data/lib/statsample-ekatena/reliability/skillscaleanalysis.rb +114 -0
  92. data/lib/statsample-ekatena/resample.rb +15 -0
  93. data/lib/statsample-ekatena/shorthand.rb +125 -0
  94. data/lib/statsample-ekatena/srs.rb +169 -0
  95. data/lib/statsample-ekatena/test.rb +82 -0
  96. data/lib/statsample-ekatena/test/bartlettsphericity.rb +45 -0
  97. data/lib/statsample-ekatena/test/chisquare.rb +73 -0
  98. data/lib/statsample-ekatena/test/f.rb +52 -0
  99. data/lib/statsample-ekatena/test/kolmogorovsmirnov.rb +63 -0
  100. data/lib/statsample-ekatena/test/levene.rb +88 -0
  101. data/lib/statsample-ekatena/test/t.rb +309 -0
  102. data/lib/statsample-ekatena/test/umannwhitney.rb +208 -0
  103. data/lib/statsample-ekatena/test/wilcoxonsignedrank.rb +90 -0
  104. data/lib/statsample-ekatena/vector.rb +19 -0
  105. data/lib/statsample-ekatena/version.rb +3 -0
  106. data/lib/statsample.rb +282 -0
  107. data/po/es/statsample.mo +0 -0
  108. data/po/es/statsample.po +959 -0
  109. data/po/statsample.pot +947 -0
  110. data/references.txt +24 -0
  111. data/statsample-ekatena.gemspec +49 -0
  112. data/test/fixtures/bank2.dat +200 -0
  113. data/test/fixtures/correlation_matrix.rb +17 -0
  114. data/test/fixtures/df.csv +15 -0
  115. data/test/fixtures/hartman_23.matrix +9 -0
  116. data/test/fixtures/stock_data.csv +500 -0
  117. data/test/fixtures/tetmat_matrix.txt +5 -0
  118. data/test/fixtures/tetmat_test.txt +1001 -0
  119. data/test/helpers_tests.rb +83 -0
  120. data/test/test_analysis.rb +176 -0
  121. data/test/test_anova_contrast.rb +36 -0
  122. data/test/test_anovaoneway.rb +26 -0
  123. data/test/test_anovatwoway.rb +37 -0
  124. data/test/test_anovatwowaywithdataset.rb +47 -0
  125. data/test/test_anovawithvectors.rb +102 -0
  126. data/test/test_awesome_print_bug.rb +16 -0
  127. data/test/test_bartlettsphericity.rb +25 -0
  128. data/test/test_bivariate.rb +164 -0
  129. data/test/test_codification.rb +78 -0
  130. data/test/test_crosstab.rb +67 -0
  131. data/test/test_dominance_analysis.rb +39 -0
  132. data/test/test_factor.rb +228 -0
  133. data/test/test_factor_map.rb +38 -0
  134. data/test/test_factor_pa.rb +56 -0
  135. data/test/test_fit_model.rb +88 -0
  136. data/test/test_ggobi.rb +35 -0
  137. data/test/test_gsl.rb +15 -0
  138. data/test/test_histogram.rb +109 -0
  139. data/test/test_matrix.rb +48 -0
  140. data/test/test_multiset.rb +176 -0
  141. data/test/test_regression.rb +231 -0
  142. data/test/test_reliability.rb +223 -0
  143. data/test/test_reliability_icc.rb +198 -0
  144. data/test/test_reliability_skillscale.rb +57 -0
  145. data/test/test_resample.rb +24 -0
  146. data/test/test_srs.rb +9 -0
  147. data/test/test_statistics.rb +69 -0
  148. data/test/test_stest.rb +69 -0
  149. data/test/test_stratified.rb +17 -0
  150. data/test/test_test_f.rb +33 -0
  151. data/test/test_test_kolmogorovsmirnov.rb +34 -0
  152. data/test/test_test_t.rb +62 -0
  153. data/test/test_umannwhitney.rb +27 -0
  154. data/test/test_vector.rb +12 -0
  155. data/test/test_wilcoxonsignedrank.rb +64 -0
  156. metadata +570 -0
@@ -0,0 +1,100 @@
1
+ require 'statsample/analysis/suite'
2
+ require 'statsample/analysis/suitereportbuilder'
3
+
4
+ module Statsample
5
+ # DSL to create analysis without hazzle.
6
+ # * Shortcuts methods to avoid use complete namescapes, many based on R
7
+ # * Attach/detach vectors to workspace, like R
8
+ # == Example
9
+ # an1=Statsample::Analysis.store(:first) do
10
+ # # Load excel file with x,y,z vectors
11
+ # ds=excel('data.xls')
12
+ # # See variables on ds dataset
13
+ # names(ds)
14
+ # # Attach the vectors to workspace, like R
15
+ # attach(ds)
16
+ # # vector 'x' is attached to workspace like a method,
17
+ # # so you can use like any variable
18
+ # mean,sd=x.mean, x.sd
19
+ # # Shameless R robbery
20
+ # a=c( 1:10)
21
+ # b=c(21:30)
22
+ # summary(cor(ds)) # Call summary method on correlation matrix
23
+ # end
24
+ # # You can run the analysis by its name
25
+ # Statsample::Analysis.run(:first)
26
+ # # or using the returned variables
27
+ # an1.run
28
+ # # You can also generate a report using ReportBuilder.
29
+ # # .summary() method call 'report_building' on the object,
30
+ # # instead of calling text summary
31
+ # an1.generate("report.html")
32
+ module Analysis
33
+ @@stored_analysis={}
34
+ @@last_analysis=nil
35
+ def self.clear_analysis
36
+ @@stored_analysis.clear
37
+ end
38
+ def self.stored_analysis
39
+ @@stored_analysis
40
+ end
41
+ def self.last
42
+ @@stored_analysis[@@last_analysis]
43
+ end
44
+ def self.store(name, opts=Hash.new,&block)
45
+ raise "You should provide a block" if !block
46
+ @@last_analysis=name
47
+ opts={:name=>name}.merge(opts)
48
+ @@stored_analysis[name]=Suite.new(opts,&block)
49
+ end
50
+ # Run analysis +*args+
51
+ # Without arguments, run all stored analysis
52
+ # Only 'echo' will be returned to screen
53
+ def self.run(*args)
54
+ args=stored_analysis.keys if args.size==0
55
+ raise "Analysis #{args} doesn't exists" if (args - stored_analysis.keys).size>0
56
+ args.each do |name|
57
+ stored_analysis[name].run
58
+ end
59
+ end
60
+
61
+ # Add analysis +*args+ to an reportbuilder object.
62
+ # Without arguments, add all stored analysis
63
+ # Each analysis is wrapped inside a ReportBuilder::Section object
64
+ # This is the method is used by save() and to_text()
65
+
66
+ def self.add_to_reportbuilder(rb, *args)
67
+ args=stored_analysis.keys if args.size==0
68
+ raise "Analysis #{name} doesn't exists" if (args - stored_analysis.keys).size>0
69
+ args.each do |name|
70
+ section=ReportBuilder::Section.new(:name=>stored_analysis[name].name)
71
+ rb_an=stored_analysis[name].add_to_reportbuilder(section)
72
+ rb.add(section)
73
+ rb_an.run
74
+ end
75
+ end
76
+
77
+ # Save the analysis on a file
78
+ # Without arguments, add all stored analysis
79
+ def self.save(filename, *args)
80
+ rb=ReportBuilder.new(:name=>filename)
81
+ add_to_reportbuilder(rb, *args)
82
+ rb.save(filename)
83
+ end
84
+
85
+ # Run analysis and return as string
86
+ # output of echo callings
87
+ # Without arguments, add all stored analysis
88
+
89
+ def self.to_text(*args)
90
+ rb=ReportBuilder.new(:name=>"Analysis #{Time.now}")
91
+ add_to_reportbuilder(rb, *args)
92
+ rb.to_text
93
+ end
94
+ # Run analysis and return to screen all
95
+ # echo and summary callings
96
+ def self.run_batch(*args)
97
+ puts to_text(*args)
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,89 @@
1
+ module Statsample
2
+ module Analysis
3
+ class Suite
4
+ include Statsample::Shorthand
5
+ attr_accessor :output
6
+ attr_accessor :name
7
+ attr_reader :block
8
+ def initialize(opts=Hash.new(), &block)
9
+ if !opts.is_a? Hash
10
+ opts={:name=>opts}
11
+ end
12
+
13
+ @block=block
14
+ @name=opts[:name] || "Analysis #{Time.now}"
15
+ @attached=[]
16
+ @output=opts[:output] || ::STDOUT
17
+ end
18
+ # Run the analysis, putting output on
19
+ def run
20
+ @block.arity<1 ? instance_eval(&@block) : @block.call(self)
21
+ end
22
+ # Provides a description of the procedure. Only appears as a commentary on
23
+ # SuiteReportBuilder outputs
24
+ def desc(d)
25
+ @output.puts("Description:")
26
+ @output.puts(" #{d}")
27
+ end
28
+ def echo(*args)
29
+ @output.puts(*args)
30
+ end
31
+ def summary(obj)
32
+ obj.summary
33
+ end
34
+ def add_to_reportbuilder(rb)
35
+ SuiteReportBuilder.new({:name=>name, :rb=>rb}, &block)
36
+ end
37
+
38
+ def generate(filename)
39
+ ar=SuiteReportBuilder.new({:name=>name}, &block)
40
+ ar.generate(filename)
41
+ end
42
+ def to_text
43
+ ar=SuiteReportBuilder.new({:name=>name}, &block)
44
+ ar.to_text
45
+ end
46
+
47
+ def attach(ds)
48
+ @attached.push(ds)
49
+ end
50
+ def detach(ds=nil)
51
+ if ds.nil?
52
+ @attached.pop
53
+ else
54
+ @attached.delete(ds)
55
+ end
56
+ end
57
+ alias :old_boxplot :boxplot
58
+ alias :old_histogram :histogram
59
+ alias :old_scatterplot :scatterplot
60
+
61
+ def show_svg(svg)
62
+ require 'tmpdir'
63
+ fn=Dir.tmpdir+"/image_#{Time.now.to_f}.svg"
64
+ File.open(fn,"w") {|fp| fp.write svg}
65
+ if RUBY_PLATFORM =~/darwin/
66
+ %x(open -a safari #{fn})
67
+ else
68
+ %x(xdg-open #{fn})
69
+ end
70
+ end
71
+ def boxplot(*args)
72
+ show_svg(old_boxplot(*args).to_svg)
73
+ end
74
+ def histogram(*args)
75
+ show_svg(old_histogram(*args).to_svg)
76
+ end
77
+ def scatterplot(*args)
78
+ show_svg(old_scatterplot(*args).to_svg)
79
+ end
80
+
81
+ def method_missing(name, *args,&block)
82
+ @attached.reverse.each do |ds|
83
+ return ds[name] if ds.vectors.to_a.include? (name)
84
+ end
85
+ raise "Method #{name} doesn't exists"
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,44 @@
1
+ module Statsample
2
+ module Analysis
3
+ class SuiteReportBuilder < Suite
4
+ attr_accessor :rb
5
+ def initialize(opts=Hash.new,&block)
6
+ if !opts.is_a? Hash
7
+ opts={:name=>opts}
8
+ end
9
+ super(opts,&block)
10
+ @rb=opts[:rb] || ReportBuilder.new(:name=>name)
11
+ end
12
+ def generate(filename)
13
+ run if @block
14
+ @rb.save(filename)
15
+ end
16
+ def to_text
17
+ run if @block
18
+ @rb.to_text
19
+ end
20
+ def summary(o)
21
+ @rb.add(o)
22
+ end
23
+ def desc(d)
24
+ @rb.add(d)
25
+ end
26
+ def echo(*args)
27
+ args.each do |a|
28
+ @rb.add(a)
29
+ end
30
+ end
31
+
32
+ def boxplot(*args)
33
+ @rb.add(old_boxplot(*args))
34
+ end
35
+ def histogram(*args)
36
+ @rb.add(old_histogram(*args))
37
+ end
38
+ def boxplot(*args)
39
+ @rb.add(old_boxplot(*args))
40
+ end
41
+
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,24 @@
1
+ module Statsample
2
+ module Anova
3
+ class << self
4
+ def oneway(*args)
5
+ OneWay.new(*args)
6
+ end
7
+ def twoway(*args)
8
+ TwoWay.new(*args)
9
+ end
10
+
11
+ def oneway_with_vectors(*args)
12
+ OneWayWithVectors.new(*args)
13
+ end
14
+ def twoway_with_vectors(*args)
15
+ TwoWayWithVectors.new(*args)
16
+ end
17
+
18
+ end
19
+ end
20
+ end
21
+
22
+ require 'statsample/anova/oneway'
23
+ require 'statsample/anova/contrast'
24
+ require 'statsample/anova/twoway'
@@ -0,0 +1,79 @@
1
+ module Statsample
2
+ module Anova
3
+ class Contrast
4
+ attr_reader :psi
5
+
6
+ attr_reader :msw
7
+ include Summarizable
8
+ def initialize(opts=Hash.new)
9
+ raise "Should set at least vectors options" if opts[:vectors].nil?
10
+ @vectors=opts[:vectors]
11
+ @c=opts[:c]
12
+ @c1,@c2=opts[:c1], opts[:c2]
13
+ @t_options=opts[:t_options] || {:estimate_name=>_("Psi estimate")}
14
+ @name=opts[:name] || _("Contrast")
15
+ @psi=nil
16
+ @anova=Statsample::Anova::OneWayWithVectors.new(@vectors)
17
+ @msw=@anova.msw
18
+ end
19
+ # Hypothesis contrast, selecting index for each constrast
20
+ # For example, if you want to contrast x_0 against x_1 and x_2
21
+ # you should use
22
+ # c.contrast([0],[1,2])
23
+ def c_by_index(c1,c2)
24
+ contrast=[0]*@vectors.size
25
+ c1.each {|i| contrast[i]=1.quo(c1.size)}
26
+ c2.each {|i| contrast[i]=-1.quo(c2.size)}
27
+ @c=contrast
28
+ c(contrast)
29
+ end
30
+ def psi
31
+ if @psi.nil?
32
+ c(@c) if @c
33
+ c_by_index(@c1,@c2) if (@c1 and @c2)
34
+ end
35
+ @psi
36
+ end
37
+ def confidence_interval(cl=nil)
38
+ t_object.confidence_interval(cl)
39
+ end
40
+ # Hypothesis contrast, using custom values
41
+ # Every parameter is a contrast value. You should use
42
+ # the same number of contrast as vectors on class and the sum
43
+ # of constrast should be 0.
44
+ def c(args=nil)
45
+
46
+ return @c if args.nil?
47
+ @c=args
48
+ raise "contrast number!=vector number" if args.size!=@vectors.size
49
+ #raise "Sum should be 0" if args.inject(0) {|ac,v| ac+v}!=0
50
+ @psi=args.size.times.inject(0) {|ac,i| ac+(args[i]*@vectors[i].mean)}
51
+ end
52
+ def standard_error
53
+ sum=@vectors.size.times.inject(0) {|ac,i|
54
+ ac+((@c[i].rationalize**2).quo(@vectors[i].size))
55
+ }
56
+ Math.sqrt(@msw*sum)
57
+ end
58
+ alias :se :standard_error
59
+ def df
60
+ @vectors.inject(0) {|ac,v| ac+v.size}-@vectors.size
61
+ end
62
+ def t_object
63
+ Statsample::Test::T.new(psi, se, df, @t_options)
64
+ end
65
+ def t
66
+ t_object.t
67
+ end
68
+ def probability
69
+ t_object.probability
70
+ end
71
+ def report_building(builder)
72
+ builder.section(:name=>@name) do |s|
73
+ s.text _("Contrast:%s") % c.join(",")
74
+ s.parse_element(t_object)
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,187 @@
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
+ @name=@name_numerator=@name_denominator=nil
17
+
18
+ # First see if sum of squares or mean squares are entered
19
+ raise ArgumentError, "You should set d.f." unless (opts.has_key? :df_num and opts.has_key? :df_den)
20
+ @df_num=opts.delete :df_num
21
+ @df_den=opts.delete :df_den
22
+ @df_total=@df_num+@df_den
23
+ if(opts.has_key? :ss_num and opts.has_key? :ss_den)
24
+ @ss_num = opts.delete :ss_num
25
+ @ss_den =opts.delete :ss_den
26
+ @ms_num =@ss_num.quo(@df_num)
27
+ @ms_den =@ss_den.quo(@df_den)
28
+ elsif (opts.has_key? :ms_num and opts.has_key? :ms_den)
29
+ @ms_num =opts.delete :ms_num
30
+ @ms_den =opts.delete :ms_den
31
+ @ss_num =@ms_num * @df_num
32
+ @ss_den =@ss_den * @df_den
33
+ end
34
+ @ss_total=@ss_num+@ss_den
35
+ @ms_total=@ms_num+@ms_den
36
+ opts_default={:name=>"ANOVA",
37
+ :name_denominator=>_("Explained variance"),
38
+ :name_numerator=>_("Unexplained variance")}
39
+ @opts=opts_default.merge(opts)
40
+ opts.keys.each {|k|
41
+ send("#{k}=", @opts[k]) if self.respond_to? "#{k}="
42
+ }
43
+ @f_object=Statsample::Test::F.new(@ms_num, @ms_den, @df_num,@df_den)
44
+ end
45
+ # F value
46
+ def f
47
+ @f_object.f
48
+ end
49
+ # P-value of F test
50
+ def probability
51
+ @f_object.probability
52
+ end
53
+ def report_building(builder) #:nodoc:
54
+ builder.section(:name=>@name) do |b|
55
+ report_building_table(b)
56
+ end
57
+ end
58
+ def report_building_table(builder) #:nodoc:
59
+ builder.table(:name=>_("%s Table") % @name, :header=>%w{source ss df ms f p}.map {|v| _(v)}) do |t|
60
+ t.row([@name_numerator, sprintf("%0.3f",@ss_num), @df_num, sprintf("%0.3f",@ms_num), sprintf("%0.3f",f), sprintf("%0.3f", probability)])
61
+ t.row([@name_denominator, sprintf("%0.3f",@ss_den), @df_den, sprintf("%0.3f",@ms_den), "", ""])
62
+ t.row([_("Total"), sprintf("%0.3f",@ss_total), @df_total, sprintf("%0.3f",@ms_total),"",""])
63
+ end
64
+ end
65
+
66
+ end
67
+
68
+ # One Way Anova with vectors
69
+ # Example:
70
+ # v1 = Daru::Vector.new([2,3,4,5,6])
71
+ # v2 = Daru::Vector.new([3,3,4,5,6])
72
+ # v3 = Daru::Vector.new([5,3,1,5,6])
73
+ # anova=Statsample::Anova::OneWayWithVectors.new([v1,v2,v3])
74
+ # anova.f
75
+ # => 0.0243902439024391
76
+ # anova.probability
77
+ # => 0.975953044203438
78
+ # anova.sst
79
+ # => 32.9333333333333
80
+ #
81
+ class OneWayWithVectors < OneWay
82
+ # Show on summary Levene test
83
+ attr_accessor :summary_levene
84
+ # Show on summary descriptives for vectors
85
+ attr_accessor :summary_descriptives
86
+ # Show on summary of contrasts
87
+ attr_accessor :summary_contrasts
88
+ # Array with stored contrasts
89
+ attr_reader :contrasts
90
+
91
+ def initialize(*args)
92
+ if args[0].is_a? Array
93
+ @vectors = args.shift
94
+ else
95
+ @vectors = args.find_all {|v| v.is_a? Daru::Vector}
96
+ opts = args.find {|v| v.is_a? Hash}
97
+ end
98
+ opts||=Hash.new
99
+ opts_default={:name=>_("Anova One-Way"),
100
+ :name_numerator=>_("Between Groups"),
101
+ :name_denominator=>_("Within Groups"),
102
+ :summary_descriptives=>false,
103
+ :summary_levene=>true,
104
+ :summary_contrasts=>true
105
+ }
106
+ @opts=opts_default.merge(opts).merge(:ss_num=>ssbg, :ss_den=>sswg, :df_num=>df_bg, :df_den=>df_wg)
107
+ @contrasts=[]
108
+ super(@opts)
109
+ end
110
+ alias :sst :ss_total
111
+ alias :msb :ms_num
112
+ alias :msw :ms_den
113
+
114
+ # Generates and store a contrast.
115
+ # Options should be provided as a hash
116
+ # [:c]=>contrast vector
117
+ # [:c1 - :c2]=>index for automatic construction of contrast
118
+ # [:name]=>contrast name
119
+
120
+ def contrast(opts=Hash.new)
121
+ name=opts[:name] || _("Contrast for %s") % @name
122
+ opts=opts.merge({:vectors=>@vectors, :name=>name})
123
+ c=Statsample::Anova::Contrast.new(opts)
124
+ @contrasts.push(c)
125
+ c
126
+ end
127
+
128
+ def levene
129
+ Statsample::Test.levene(@vectors, :name=>_("Test of Homogeneity of variances (Levene)"))
130
+ end
131
+ # Total mean
132
+ def total_mean
133
+ sum=@vectors.inject(0){|a,v| a+v.sum}
134
+ sum.quo(n)
135
+ end
136
+ # Sum of squares within groups
137
+ def sswg
138
+ @sswg||=@vectors.inject(0) {|total,vector| total+vector.ss }
139
+ end
140
+ # Sum of squares between groups
141
+ def ssbg
142
+ m=total_mean
143
+ @vectors.inject(0) do |total,vector|
144
+ total + (vector.mean-m).square * vector.size
145
+ end
146
+ end
147
+ # Degrees of freedom within groups
148
+ def df_wg
149
+ @dk_wg||=n-k
150
+ end
151
+ def k
152
+ @k||=@vectors.size
153
+ end
154
+ # Degrees of freedom between groups
155
+ def df_bg
156
+ k-1
157
+ end
158
+ # Total number of cases
159
+ def n
160
+ @vectors.inject(0){|a,v| a+v.size}
161
+ end
162
+ def report_building(builder) # :nodoc:
163
+ builder.section(:name=>@name) do |s|
164
+ if summary_descriptives
165
+ s.table(:name=>_("Descriptives"),:header=>%w{Name N Mean SD Min Max}.map {|v| _(v)}) do |t|
166
+ @vectors.each do |v|
167
+ t.row [v.name, v.reject_values(*Daru::MISSING_VALUES).size, "%0.4f" % v.mean, "%0.4f" % v.sd, "%0.4f" % v.min, "%0.4f" % v.max]
168
+ end
169
+ end
170
+ end
171
+
172
+ if summary_levene
173
+ s.parse_element(levene)
174
+ end
175
+ report_building_table(s)
176
+ if summary_contrasts and @contrasts.size>0
177
+
178
+ @contrasts.each do |c|
179
+ s.parse_element(c)
180
+ end
181
+ end
182
+
183
+ end
184
+ end
185
+ end
186
+ end
187
+ end