statsample 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -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
@@ -57,6 +57,7 @@ module Statsample
57
57
  t.quo(v2s.size-1)
58
58
  =end
59
59
  end
60
+ alias :correlation :pearson
60
61
  # Retrieves the value for t test for a pearson correlation
61
62
  # between two vectors to test the null hipothesis of r=0
62
63
  def t_pearson(v1,v2)
@@ -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
- include GetText
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", md([f]).r2)
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{|p|
359
- name=p.join(" - ")
360
- row=[name, sprintf("%0.1f",td[p]), sprintf("%0.1f",cd[p]), sprintf("%0.1f",gd[p])]
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
- begin
398
- sign=sprintf("%0.3f", @lr.significance)
399
- rescue RuntimeError
400
- sign="???"
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
- ds_bootstrap[f]=@n_cases.times.map {|c| rng.gaussian( @ds[f].sd)+@ds[f].mean}.to_scale
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
@@ -43,6 +43,12 @@ module Statsample
43
43
  yield k, v[field]
44
44
  }
45
45
  end
46
+
47
+ def each_vector(field)
48
+ @datasets.each {|k,v|
49
+ yield k, v[field]
50
+ }
51
+ end
46
52
  def[](i)
47
53
  @datasets[i]
48
54
  end
@@ -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
- t.row([_("Constant"), sprintf("%0.3f", constant), "-", sprintf("%0.3f", constant_se), sprintf("%0.3f", constant_t)])
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
- sum_var_items=ds.vectors.inject(0) {|ac,v|
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-(sum_var_items.quo(total.variance)))
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