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
@@ -0,0 +1,211 @@
|
|
1
|
+
module Statsample
|
2
|
+
module Anova
|
3
|
+
# = Generic Anova two-way.
|
4
|
+
# You could enter the sum of squares or the mean squares for a, b, axb and within.
|
5
|
+
# You should enter the degrees of freedom for a,b and within, because df_axb=df_a*df_b
|
6
|
+
# == Usage
|
7
|
+
# anova=Statsample::Anova::TwoWay(:ss_a=>10,:ss_b=>20,:ss_axb=>10, :ss_within=>20, :df_a=>2, :df_b=>3,df_within=100 @name=>"ANOVA for....")
|
8
|
+
class TwoWay
|
9
|
+
include Summarizable
|
10
|
+
attr_reader :df_a, :df_b, :df_axb, :df_within, :df_total
|
11
|
+
attr_reader :ss_a, :ss_b, :ss_axb, :ss_within, :ss_total
|
12
|
+
attr_reader :ms_a, :ms_b, :ms_axb, :ms_within, :ms_total
|
13
|
+
# Name of ANOVA Analisys
|
14
|
+
attr_accessor :name
|
15
|
+
# Name of a factor
|
16
|
+
attr_accessor :name_a
|
17
|
+
# Name of b factor
|
18
|
+
attr_accessor :name_b
|
19
|
+
# Name of within factor
|
20
|
+
attr_accessor :name_within
|
21
|
+
|
22
|
+
attr_reader :f_a_object, :f_b_object, :f_axb_object
|
23
|
+
def initialize(opts=Hash.new)
|
24
|
+
# First see if sum of squares or mean squares are entered
|
25
|
+
raise ArgumentError, "You should set all d.f." unless [:df_a, :df_b, :df_within].all? {|v| opts.has_key? v}
|
26
|
+
|
27
|
+
@df_a=opts.delete :df_a
|
28
|
+
@df_b=opts.delete :df_b
|
29
|
+
@df_axb=@df_a*@df_b
|
30
|
+
@df_within=opts.delete :df_within
|
31
|
+
@df_total=@df_a+@df_b+@df_axb+@df_within
|
32
|
+
|
33
|
+
if [:ss_a, :ss_b, :ss_axb, :ss_within].all? {|v| opts.has_key? v}
|
34
|
+
@ss_a = opts.delete :ss_a
|
35
|
+
@ss_b = opts.delete :ss_b
|
36
|
+
@ss_axb = opts.delete :ss_axb
|
37
|
+
@ss_within = opts.delete :ss_within
|
38
|
+
|
39
|
+
@ms_a =@ss_a.quo(@df_a)
|
40
|
+
@ms_b =@ss_b.quo(@df_b)
|
41
|
+
@ms_axb =@ss_axb.quo(@df_axb)
|
42
|
+
@ms_within =@ss_within.quo(@df_within)
|
43
|
+
|
44
|
+
elsif [:ms_a, :ms_b, :ms_axb, :ms_within].all? {|v| opts.has_key? v}
|
45
|
+
@ms_a = opts.delete :ms_a
|
46
|
+
@ms_b = opts.delete :ms_b
|
47
|
+
@ms_axb = opts.delete :ms_axb
|
48
|
+
@ms_within = opts.delete :ms_within
|
49
|
+
|
50
|
+
@ss_a =@ms_a*@df_a
|
51
|
+
@ss_b =@ms_b*@df_b
|
52
|
+
@ss_axb =@ms_axb*@df_axb
|
53
|
+
@ss_within =@ms_within*@df_within
|
54
|
+
else
|
55
|
+
raise "You should set all ss or ss"
|
56
|
+
end
|
57
|
+
@ss_total=@ss_a+@ss_b+@ss_axb+@ss_within
|
58
|
+
@ms_total=@ms_a+@ms_b+@ms_axb+@ms_within
|
59
|
+
opts_default={:name=>_("ANOVA Two-Way"),
|
60
|
+
:name_a=>_("A"),
|
61
|
+
:name_b=>_("B"),
|
62
|
+
:name_within=>_("Within")
|
63
|
+
}
|
64
|
+
@opts=opts_default.merge(opts)
|
65
|
+
opts_default.keys.each {|k|
|
66
|
+
send("#{k}=", @opts[k])
|
67
|
+
}
|
68
|
+
@f_a_object=Statsample::Test::F.new(@ms_a,@ms_within,@df_a,@df_within)
|
69
|
+
@f_b_object=Statsample::Test::F.new(@ms_b,@ms_within,@df_b,@df_within)
|
70
|
+
@f_axb_object=Statsample::Test::F.new(@ms_axb,@ms_within,@df_axb,@df_within)
|
71
|
+
end
|
72
|
+
def f_a
|
73
|
+
@f_a_object.f
|
74
|
+
end
|
75
|
+
def f_b
|
76
|
+
@f_b_object.f
|
77
|
+
end
|
78
|
+
def f_axb
|
79
|
+
@f_axb_object.f
|
80
|
+
end
|
81
|
+
def f_a_probability
|
82
|
+
@f_a_object.probability
|
83
|
+
end
|
84
|
+
def f_b_probability
|
85
|
+
@f_b_object.probability
|
86
|
+
end
|
87
|
+
def f_axb_probability
|
88
|
+
@f_axb_object.probability
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
def report_building(builder) #:nodoc:
|
93
|
+
builder.section(:name=>@name) do |b|
|
94
|
+
report_building_table(b)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
def report_building_table(builder) #:nodoc:
|
98
|
+
builder.table(:name=>_("%s Table") % @name, :header=>%w{source ss df ms f p}.map {|v| _(v)}) do |t|
|
99
|
+
t.row([@name_a, "%0.3f" % @ss_a, @df_a, "%0.3f" % @ms_a , "%0.3f" % f_a, "%0.4f" % f_a_probability] )
|
100
|
+
t.row([@name_b, "%0.3f" % @ss_b, @df_b, "%0.3f" % @ms_b , "%0.3f" % f_b, "%0.4f" % f_b_probability] )
|
101
|
+
t.row(["%s X %s" % [@name_a, @name_b], "%0.3f" % @ss_axb, @df_axb, "%0.3f" % @ms_axb , "%0.3f" % f_axb, "%0.4f" % f_axb_probability] )
|
102
|
+
t.row([@name_within, "%0.3f" % @ss_within, @df_within, nil,nil,nil] )
|
103
|
+
t.row([_("Total"), "%0.3f" % @ss_total, @df_total, nil,nil,nil] )
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Two Way Anova with vectors
|
109
|
+
# Example:
|
110
|
+
# v1=[2,3,4,5,6].to_scale
|
111
|
+
# v2=[3,3,4,5,6].to_scale
|
112
|
+
# v3=[5,3,1,5,6].to_scale
|
113
|
+
# anova=Statsample::Anova::OneWayWithVectors.new([v1,v2,v3])
|
114
|
+
# anova.f
|
115
|
+
# => 0.0243902439024391
|
116
|
+
# anova.probability
|
117
|
+
# => 0.975953044203438
|
118
|
+
# anova.sst
|
119
|
+
# => 32.9333333333333
|
120
|
+
#
|
121
|
+
class TwoWayWithVectors < TwoWay
|
122
|
+
# Show summary Levene test
|
123
|
+
attr_accessor :summary_levene
|
124
|
+
# Show summary descriptives for variables (means)
|
125
|
+
attr_accessor :summary_descriptives
|
126
|
+
attr_reader :a_var, :b_var, :dep_var
|
127
|
+
# For now, only equal sample cells allowed
|
128
|
+
def initialize(opts=Hash.new)
|
129
|
+
raise "You should insert at least :a, :b and :dependent" unless [:a, :b, :dependent].all? {|v| opts.has_key? v}
|
130
|
+
@a_var='a'
|
131
|
+
@b_var='b'
|
132
|
+
@dep_var='dependent'
|
133
|
+
@a_vector, @b_vector, @dep_vector=Statsample.only_valid_clone opts[:a], opts[:b], opts[:dependent]
|
134
|
+
|
135
|
+
ds={@a_var=>@a_vector, @b_var=>@b_vector, @dep_var=>@dep_vector}.to_dataset
|
136
|
+
@ds=ds.clone_only_valid
|
137
|
+
_p=@a_vector.factors.size
|
138
|
+
_q=@b_vector.factors.size
|
139
|
+
@x_general=@dep_vector.mean
|
140
|
+
@axb_means={}
|
141
|
+
@axb_sd={}
|
142
|
+
@vectors=[]
|
143
|
+
n=nil
|
144
|
+
@ds.to_multiset_by_split(a_var,b_var).each_vector(dep_var) {|k,v|
|
145
|
+
@axb_means[k]=v.mean
|
146
|
+
@axb_sd[k]=v.sd
|
147
|
+
@vectors << v
|
148
|
+
n||=v.size
|
149
|
+
raise "All cell sizes should be equal" if n!=v.size
|
150
|
+
}
|
151
|
+
|
152
|
+
@a_means={}
|
153
|
+
@ds.to_multiset_by_split(a_var).each_vector(dep_var) {|k,v|
|
154
|
+
@a_means[k]=v.mean
|
155
|
+
}
|
156
|
+
@b_means={}
|
157
|
+
@ds.to_multiset_by_split(b_var).each_vector(dep_var) {|k,v|
|
158
|
+
@b_means[k]=v.mean
|
159
|
+
}
|
160
|
+
ss_a=n*_q*@ds[a_var].factors.inject(0) {|ac,v|
|
161
|
+
ac+(@a_means[v]-@x_general)**2
|
162
|
+
}
|
163
|
+
ss_b=n*_p*@ds[b_var].factors.inject(0) {|ac,v|
|
164
|
+
ac+(@b_means[v]-@x_general)**2
|
165
|
+
}
|
166
|
+
ss_within=@ds.collect {|row|
|
167
|
+
(row[dep_var]-@axb_means[[row[a_var],row[b_var]]])**2
|
168
|
+
}.sum
|
169
|
+
ss_axb=n*@axb_means.inject(0) {|ac,v|
|
170
|
+
j,k=v[0]
|
171
|
+
xjk=v[1]
|
172
|
+
ac+(xjk-@a_means[j]-@b_means[k]+@x_general)**2
|
173
|
+
}
|
174
|
+
df_a=_p-1
|
175
|
+
df_b=_q-1
|
176
|
+
df_within=(_p*_q)*(n-1)
|
177
|
+
|
178
|
+
opts_default={:name=>_("Anova Two-Way on #{@ds[dep_var].name}"),
|
179
|
+
:name_a=>@ds[a_var].name,
|
180
|
+
:name_b=>@ds[b_var].name,
|
181
|
+
:summary_descriptives=>true,
|
182
|
+
:summary_levene=>false}
|
183
|
+
|
184
|
+
@opts=opts_default.merge(opts).merge({:ss_a=>ss_a,:ss_b=>ss_b, :ss_axb=>ss_axb, :ss_within=>ss_within, :df_a=>df_a, :df_b=>df_b, :df_within=>df_within})
|
185
|
+
|
186
|
+
|
187
|
+
super(@opts)
|
188
|
+
end
|
189
|
+
def levene
|
190
|
+
Statsample::Test.levene(@vectors, :name=>_("Test of Homogeneity of variances (Levene)"))
|
191
|
+
end
|
192
|
+
def report_building(builder) #:nodoc:#
|
193
|
+
builder.section(:name=>@name) do |s|
|
194
|
+
if summary_descriptives
|
195
|
+
s.table(:header =>['']+@ds[a_var].factors.map {|a| @ds[a_var].labeling(a)}+[_("%s Mean") % @name_b]) do |t|
|
196
|
+
@ds[b_var].factors.each do |b|
|
197
|
+
t.row([@ds[b_var].labeling(b)]+@ds[a_var].factors.map {|a| "%0.3f" % @axb_means[[a,b]] } + ["%0.3f" % @b_means[b]])
|
198
|
+
end
|
199
|
+
t.row([_("%s Mean") % @name_a]+@ds[a_var].factors.map {|a| "%0.3f" % @a_means[a]}+ ["%0.3f" % @x_general])
|
200
|
+
end
|
201
|
+
end
|
202
|
+
if summary_levene
|
203
|
+
s.parse_element(levene)
|
204
|
+
end
|
205
|
+
report_building_table(s)
|
206
|
+
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
data/lib/statsample/bivariate.rb
CHANGED
data/lib/statsample/dataset.rb
CHANGED
@@ -186,6 +186,17 @@ module Statsample
|
|
186
186
|
}
|
187
187
|
Dataset.new(vectors,fields)
|
188
188
|
end
|
189
|
+
def clone_only_valid(*fields_to_include)
|
190
|
+
if fields_to_include.size==1 and fields_to_include[0].is_a? Array
|
191
|
+
fields_to_include=fields_to_include[0]
|
192
|
+
end
|
193
|
+
fields_to_include=@fields.dup if fields_to_include.size==0
|
194
|
+
if fields_to_include.any? {|v| @vectors[v].has_missing_data?}
|
195
|
+
dup_only_valid(fields_to_include)
|
196
|
+
else
|
197
|
+
clone(fields_to_include)
|
198
|
+
end
|
199
|
+
end
|
189
200
|
# Returns a shallow copy of Dataset.
|
190
201
|
# Object id will be distinct, but @vectors will be the same.
|
191
202
|
def clone(*fields_to_include)
|
@@ -199,6 +210,7 @@ module Statsample
|
|
199
210
|
ds[f]=@vectors[f]
|
200
211
|
}
|
201
212
|
ds.fields=fields_to_include
|
213
|
+
ds.update_valid_data
|
202
214
|
ds
|
203
215
|
end
|
204
216
|
# Creates a copy of the given dataset, without data on vectors
|
@@ -643,8 +655,10 @@ module Statsample
|
|
643
655
|
end
|
644
656
|
end
|
645
657
|
ms=Multiset.new_empty_vectors(@fields,factors_total)
|
658
|
+
|
646
659
|
p1=eval "Proc.new {|c| ms[["+fields.collect{|f| "c['#{f}']"}.join(",")+"]].add_case(c,false) }"
|
647
660
|
each{|c| p1.call(c)}
|
661
|
+
|
648
662
|
ms.datasets.each do |k,ds|
|
649
663
|
ds.update_valid_data
|
650
664
|
ds.vectors.each{|k1,v1| v1.type=@vectors[k1].type }
|
@@ -792,8 +806,8 @@ module Statsample
|
|
792
806
|
def report_building(b)
|
793
807
|
b.section(:name=>@name) do |g|
|
794
808
|
g.text _"Cases: %d" % cases
|
795
|
-
|
796
809
|
@fields.each do |f|
|
810
|
+
g.text "Element:[#{f}]"
|
797
811
|
g.parse_element(@vectors[f])
|
798
812
|
end
|
799
813
|
end
|
@@ -57,8 +57,7 @@ module Statsample
|
|
57
57
|
# * Azen, R. & Budescu, D.V. (2006). Comparing predictors in Multivariate Regression Models: An extension of Dominance Analysis. <em>Journal of Educational and Behavioral Statistics, 31</em>(2), 157-180.
|
58
58
|
#
|
59
59
|
class DominanceAnalysis
|
60
|
-
|
61
|
-
bindtextdomain("statsample")
|
60
|
+
include Summarizable
|
62
61
|
# Class to generate the regressions. Default to Statsample::Regression::Multiple::MatrixEngine
|
63
62
|
attr_accessor :regression_class
|
64
63
|
# Name of analysis
|
@@ -312,14 +311,12 @@ module Statsample
|
|
312
311
|
|
313
312
|
def report_building(g)
|
314
313
|
compute if @models.nil?
|
315
|
-
|
316
314
|
g.section(:name=>@name) do |generator|
|
317
315
|
header=["","r2",_("sign")]+@predictors.collect {|c| DominanceAnalysis.predictor_name(c) }
|
318
316
|
|
319
317
|
generator.table(:name=>_("Dominance Analysis result"), :header=>header) do |t|
|
320
|
-
|
321
318
|
row=[_("Model 0"),"",""]+@predictors.collect{|f|
|
322
|
-
sprintf("%0.3f",
|
319
|
+
sprintf("%0.3f",md([f]).r2)
|
323
320
|
}
|
324
321
|
|
325
322
|
t.row(row)
|
@@ -349,15 +346,15 @@ module Statsample
|
|
349
346
|
sprintf("%0.3f",g[f])
|
350
347
|
}
|
351
348
|
t.row(row)
|
352
|
-
end
|
349
|
+
end
|
353
350
|
|
354
351
|
td=total_dominance
|
355
352
|
cd=conditional_dominance
|
356
353
|
gd=general_dominance
|
357
354
|
generator.table(:name=>_("Pairwise dominance"), :header=>[_("Pairs"),_("Total"),_("Conditional"),_("General")]) do |t|
|
358
|
-
pairs.each{|
|
359
|
-
name=
|
360
|
-
row=[name, sprintf("%0.1f",td[
|
355
|
+
pairs.each{|pair|
|
356
|
+
name=pair.map{|v| v.is_a?(Array) ? "("+v.join("-")+")" : v}.join(" - ")
|
357
|
+
row=[name, sprintf("%0.1f",td[pair]), sprintf("%0.1f",cd[pair]), sprintf("%0.1f",gd[pair])]
|
361
358
|
t.row(row)
|
362
359
|
}
|
363
360
|
end
|
@@ -394,10 +391,10 @@ module Statsample
|
|
394
391
|
}.join("*")
|
395
392
|
end
|
396
393
|
def add_table_row
|
397
|
-
|
398
|
-
sign=sprintf("%0.3f", @lr.
|
399
|
-
|
400
|
-
|
394
|
+
if @cases
|
395
|
+
sign=sprintf("%0.3f", @lr.probability)
|
396
|
+
else
|
397
|
+
sign="???"
|
401
398
|
end
|
402
399
|
|
403
400
|
[name, sprintf("%0.3f",r2), sign] + @predictors.collect{|k|
|
@@ -100,10 +100,12 @@ class ParallelAnalysis
|
|
100
100
|
if bootstrap_method==:parameter
|
101
101
|
rng = GSL::Rng.alloc()
|
102
102
|
end
|
103
|
-
|
104
103
|
@fields.each do |f|
|
104
|
+
|
105
105
|
if bootstrap_method==:parameter
|
106
|
-
|
106
|
+
sd=@ds[f].sd
|
107
|
+
mean=@ds[f].mean
|
108
|
+
ds_bootstrap[f]=@n_cases.times.map {|c| rng.gaussian(sd)+mean}.to_scale
|
107
109
|
elsif bootstrap_method==:raw_data
|
108
110
|
ds_bootstrap[f]=ds[f].sample_with_replacement(@n_cases).to_scale
|
109
111
|
end
|
data/lib/statsample/multiset.rb
CHANGED
@@ -185,7 +185,7 @@ module Statsample
|
|
185
185
|
sc=standarized_coeffs
|
186
186
|
cse=coeffs_se
|
187
187
|
g.table(:name=>_("Beta coefficients"), :header=>%w{coeff b beta se t}.collect{|field| _(field)} ) do |t|
|
188
|
-
|
188
|
+
t.row([_("Constant"), sprintf("%0.3f", constant), "-", constant_se.nil? ? "": sprintf("%0.3f", constant_se), constant_t.nil? ? "" : sprintf("%0.3f", constant_t)])
|
189
189
|
@fields.each do |f|
|
190
190
|
t.row([f, sprintf("%0.3f", c[f]), sprintf("%0.3f", sc[f]), sprintf("%0.3f", cse[f]), sprintf("%0.3f", c[f].quo(cse[f]))])
|
191
191
|
end
|
@@ -6,10 +6,10 @@ module Statsample
|
|
6
6
|
def cronbach_alpha(ods)
|
7
7
|
ds=ods.dup_only_valid
|
8
8
|
n_items=ds.fields.size
|
9
|
-
|
9
|
+
s2_items=ds.vectors.inject(0) {|ac,v|
|
10
10
|
ac+v[1].variance }
|
11
11
|
total=ds.vector_sum
|
12
|
-
(n_items.quo(n_items-1)) * (1-(
|
12
|
+
(n_items.quo(n_items-1)) * (1-(s2_items.quo(total.variance)))
|
13
13
|
end
|
14
14
|
# Calculate Chonbach's alpha for a given dataset
|
15
15
|
# using standarized values for every vector.
|
@@ -21,6 +21,24 @@ module Statsample
|
|
21
21
|
}.to_dataset
|
22
22
|
cronbach_alpha(ds)
|
23
23
|
end
|
24
|
+
# First derivative for alfa
|
25
|
+
# Parameters
|
26
|
+
# <tt>n</tt>: Number of items
|
27
|
+
# <tt>sx</tt>: mean of variances
|
28
|
+
# <tt>sxy</tt>: mean of covariances
|
29
|
+
|
30
|
+
def alfa_first_derivative(n,sx,sxy)
|
31
|
+
(sxy*(sx-sxy)).quo(((sxy*(n-1))+sx)**2)
|
32
|
+
end
|
33
|
+
# Second derivative for alfa
|
34
|
+
# Parameters
|
35
|
+
# <tt>n</tt>: Number of items
|
36
|
+
# <tt>sx</tt>: mean of variances
|
37
|
+
# <tt>sxy</tt>: mean of covariances
|
38
|
+
|
39
|
+
def alfa_second_derivative(n,sx,sxy)
|
40
|
+
(2*(sxy**2)*(sxy-sx)).quo(((sxy*(n-1))+sx)**3)
|
41
|
+
end
|
24
42
|
end
|
25
43
|
class ItemCharacteristicCurve
|
26
44
|
attr_reader :totals, :counts, :vector_total
|
@@ -60,10 +78,11 @@ module Statsample
|
|
60
78
|
end
|
61
79
|
end
|
62
80
|
class ItemAnalysis
|
63
|
-
attr_reader :mean, :sd,:valid_n, :alpha , :alpha_standarized
|
81
|
+
attr_reader :mean, :sd,:valid_n, :alpha , :alpha_standarized, :variances_mean, :covariances_mean
|
64
82
|
attr_accessor :name
|
65
83
|
def initialize(ds,opts=Hash.new)
|
66
84
|
@ds=ds.dup_only_valid
|
85
|
+
@k=@ds.fields.size
|
67
86
|
@total=@ds.vector_sum
|
68
87
|
@item_mean=@ds.vector_mean.mean
|
69
88
|
@mean=@total.mean
|
@@ -71,11 +90,15 @@ module Statsample
|
|
71
90
|
@skew=@total.skew
|
72
91
|
@kurtosis=@total.kurtosis
|
73
92
|
@sd = @total.sd
|
93
|
+
@variance=@total.variance
|
74
94
|
@valid_n = @total.size
|
75
95
|
opts_default={:name=>"Reliability Analisis"}
|
76
96
|
@opts=opts_default.merge(opts)
|
77
97
|
@name=@opts[:name]
|
78
|
-
|
98
|
+
# Mean for covariances and variances
|
99
|
+
@variances=@ds.fields.map {|f| @ds[f].variance}.to_scale
|
100
|
+
@variances_mean=@variances.mean
|
101
|
+
@covariances_mean=(@variance-@variances.sum).quo(@k**2-@k)
|
79
102
|
begin
|
80
103
|
@alpha = Statsample::Reliability.cronbach_alpha(ds)
|
81
104
|
@alpha_standarized = Statsample::Reliability.cronbach_alpha_standarized(ds)
|
@@ -215,15 +238,19 @@ module Statsample
|
|
215
238
|
s.table(:name=>"Summary") do |t|
|
216
239
|
t.row ["Items", @ds.fields.size]
|
217
240
|
t.row ["Total Mean", @mean]
|
241
|
+
t.row ["Total S.D.", @sd]
|
242
|
+
t.row ["Total Variance", @variance]
|
218
243
|
t.row ["Item Mean", @item_mean]
|
219
|
-
t.row ["S.D.", @sd]
|
220
244
|
t.row ["Median", @median]
|
221
245
|
t.row ["Skewness", "%0.4f" % @skew]
|
222
246
|
t.row ["Kurtosis", "%0.4f" % @kurtosis]
|
223
247
|
t.row ["Valid n", @valid_n]
|
224
248
|
t.row ["Cronbach's alpha", "%0.4f" % @alpha]
|
225
249
|
t.row ["Standarized Cronbach's alpha", "%0.4f" % @alpha_standarized]
|
250
|
+
t.row ["Variances mean", "%g" % @variances_mean]
|
251
|
+
t.row ["Covariances mean" , "%g" % @covariances_mean]
|
226
252
|
end
|
253
|
+
|
227
254
|
itc=item_total_correlation
|
228
255
|
sid=stats_if_deleted
|
229
256
|
is=item_statistics
|