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