statsample-ekatena 2.0.2

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 (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