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.
- data.tar.gz.sig +1 -2
- data/History.txt +9 -0
- data/Manifest.txt +6 -2
- data/README.txt +6 -3
- data/Rakefile +4 -19
- data/examples/dominance_analysis.rb +0 -1
- data/examples/parallel_analysis.rb +2 -1
- data/examples/parallel_analysis_tetrachoric.rb +1 -1
- data/examples/reliability.rb +12 -0
- data/lib/statsample.rb +1 -2
- data/lib/statsample/anova.rb +9 -151
- data/lib/statsample/anova/oneway.rb +151 -0
- data/lib/statsample/anova/twoway.rb +211 -0
- data/lib/statsample/bivariate.rb +1 -0
- data/lib/statsample/dataset.rb +15 -1
- data/lib/statsample/dominanceanalysis.rb +10 -13
- data/lib/statsample/factor/parallelanalysis.rb +4 -2
- data/lib/statsample/multiset.rb +6 -0
- data/lib/statsample/regression/multiple/baseengine.rb +1 -1
- data/lib/statsample/reliability.rb +32 -5
- data/lib/statsample/vector.rb +6 -5
- data/test/{test_helpers.rb → helpers_tests.rb} +2 -0
- data/test/test_anovaoneway.rb +1 -2
- data/test/test_anovatwoway.rb +38 -0
- data/test/test_anovatwowaywithdataset.rb +49 -0
- data/test/test_anovawithvectors.rb +1 -1
- data/test/test_bivariate.rb +1 -1
- data/test/test_bivariate_polychoric.rb +1 -1
- data/test/test_codification.rb +1 -1
- data/test/test_combination.rb +1 -1
- data/test/test_crosstab.rb +1 -1
- data/test/test_csv.rb +1 -1
- data/test/test_dataset.rb +8 -1
- data/test/test_distribution.rb +1 -1
- data/test/test_dominance_analysis.rb +2 -1
- data/test/test_factor.rb +1 -1
- data/test/test_ggobi.rb +1 -1
- data/test/test_gsl.rb +1 -1
- data/test/test_histogram.rb +1 -1
- data/test/test_logit.rb +1 -1
- data/test/test_matrix.rb +1 -1
- data/test/test_mle.rb +1 -1
- data/test/test_multiset.rb +1 -1
- data/test/test_permutation.rb +1 -1
- data/test/test_regression.rb +3 -4
- data/test/test_reliability.rb +15 -2
- data/test/test_resample.rb +1 -1
- data/test/test_srs.rb +1 -1
- data/test/test_statistics.rb +1 -1
- data/test/test_stest.rb +1 -1
- data/test/test_stratified.rb +1 -1
- data/test/test_svg_graph.rb +1 -1
- data/test/test_test_f.rb +1 -1
- data/test/test_test_t.rb +1 -1
- data/test/test_umannwhitney.rb +1 -1
- data/test/test_vector.rb +1 -1
- data/test/test_xls.rb +1 -1
- metadata +92 -40
- metadata.gz.sig +0 -0
- data/lib/statistics2.rb +0 -531
data.tar.gz.sig
CHANGED
@@ -1,2 +1 @@
|
|
1
|
-
|
2
|
-
`��O�c�>һ��|�c�+���}�I�ʸi�! ��fSW���]Q���#c�ۦ�+ȋ�M�l;xw{^6�q%"ry> �8��O�)�)h0�CU����ʺ]H��ϞN�<����
|
1
|
+
�����%y�ӵ���T���:�l�bt ��郧�%t���§�A�n�?2��JRw��ov��t[a 4�Ӏ%�_i�N
|
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
|
-
==
|
104
|
-
|
105
|
-
*
|
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
|
@@ -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=>
|
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")
|
@@ -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.
|
114
|
+
VERSION = '0.11.0'
|
116
115
|
SPLIT_TOKEN = ","
|
117
116
|
autoload(:Database, 'statsample/converters')
|
118
117
|
autoload(:Anova, 'statsample/anova')
|
data/lib/statsample/anova.rb
CHANGED
@@ -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
|
-
|
11
|
-
|
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
|