Class: Statsample::Reliability::ScaleAnalysis

Inherits:
Object
  • Object
show all
Includes:
Summarizable
Defined in:
lib/statsample/reliability/scaleanalysis.rb

Overview

Analysis of a Scale. Analoge of Scale Reliability analysis on SPSS. Returns several statistics for complete scale and each item

Usage

@x1 = Daru::Vector.new([1,1,1,1,2,2,2,2,3,3,3,30])
@x2 = Daru::Vector.new([1,1,1,2,2,3,3,3,3,4,4,50])
@x3 = Daru::Vector.new([2,2,1,1,1,2,2,2,3,4,5,40])
@x4 = Daru::Vector.new([1,2,3,4,4,4,4,3,4,4,5,30])
ds  = Daru::DataFrame.new({:x1 => @x1,:x2 => @x2,:x3 => @x3,:x4 => @x4})
ia  = Statsample::Reliability::ScaleAnalysis.new(ds)
puts ia.summary

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Summarizable

#summary

Constructor Details

#initialize(ds, opts = Hash.new) ⇒ ScaleAnalysis

Returns a new instance of ScaleAnalysis.



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/statsample/reliability/scaleanalysis.rb', line 18

def initialize(ds, opts=Hash.new)
  @dumped=ds.vectors.to_a.find_all {|f|
    ds[f].variance == 0
  }
  
  @ods = ds
  @ds  = ds.reject_values(*Daru::MISSING_VALUES).dup(ds.vectors.to_a - @dumped)
  @ds.rename ds.name
  
  @k     = @ds.ncols
  @total = @ds.vector_sum
  @o_total=@dumped.size > 0 ? @ods.vector_sum : nil
  
  @vector_mean = @ds.vector_mean
  @item_mean   = @vector_mean.mean
  @item_sd     = @vector_mean.sd
  
  @mean     = @total.mean
  @median   = @total.median
  @skew     = @total.skew
  @kurtosis = @total.kurtosis
  @sd       = @total.sd
  @variance = @total.variance
  @valid_n  = @total.size

  opts_default = {
    :name => _("Reliability Analysis"),
    :summary_histogram => true
  }
  @opts = opts_default.merge(opts)
  @opts.each{ |k,v| self.send("#{k}=",v) if self.respond_to? k }
  
  @cov_m=Statsample::Bivariate.covariance_matrix(@ds)
  # Mean for covariances and variances
  @variances = Daru::Vector.new(@k.times.map { |i| @cov_m[i,i] })
  @variances_mean=@variances.mean
  @covariances_mean=(@variance-@variances.sum).quo(@k**2-@k)
  #begin
    @alpha = Statsample::Reliability.cronbach_alpha(@ds)
    @alpha_standarized = Statsample::Reliability.cronbach_alpha_standarized(@ds)
  #rescue => e
  #  raise DatasetException.new(@ds,e), "Error calculating alpha"
  #end
end

Instance Attribute Details

#alphaObject (readonly)

Returns the value of attribute alpha.



15
16
17
# File 'lib/statsample/reliability/scaleanalysis.rb', line 15

def alpha
  @alpha
end

#alpha_standarizedObject (readonly)

Returns the value of attribute alpha_standarized.



15
16
17
# File 'lib/statsample/reliability/scaleanalysis.rb', line 15

def alpha_standarized
  @alpha_standarized
end

#cov_mObject (readonly)

Returns the value of attribute cov_m.



15
16
17
# File 'lib/statsample/reliability/scaleanalysis.rb', line 15

def cov_m
  @cov_m
end

#covariances_meanObject (readonly)

Returns the value of attribute covariances_mean.



15
16
17
# File 'lib/statsample/reliability/scaleanalysis.rb', line 15

def covariances_mean
  @covariances_mean
end

#dsObject (readonly)

Returns the value of attribute ds.



15
16
17
# File 'lib/statsample/reliability/scaleanalysis.rb', line 15

def ds
  @ds
end

#meanObject (readonly)

Returns the value of attribute mean.



15
16
17
# File 'lib/statsample/reliability/scaleanalysis.rb', line 15

def mean
  @mean
end

#nameObject

Returns the value of attribute name.



16
17
18
# File 'lib/statsample/reliability/scaleanalysis.rb', line 16

def name
  @name
end

#sdObject (readonly)

Returns the value of attribute sd.



15
16
17
# File 'lib/statsample/reliability/scaleanalysis.rb', line 15

def sd
  @sd
end

#summary_histogramObject

Returns the value of attribute summary_histogram.



17
18
19
# File 'lib/statsample/reliability/scaleanalysis.rb', line 17

def summary_histogram
  @summary_histogram
end

#valid_nObject (readonly)

Returns the value of attribute valid_n.



15
16
17
# File 'lib/statsample/reliability/scaleanalysis.rb', line 15

def valid_n
  @valid_n
end

#variances_meanObject (readonly)

Returns the value of attribute variances_mean.



15
16
17
# File 'lib/statsample/reliability/scaleanalysis.rb', line 15

def variances_mean
  @variances_mean
end

Instance Method Details

#item_characteristic_curveObject

Returns a hash with structure



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/statsample/reliability/scaleanalysis.rb', line 63

def item_characteristic_curve
  i=0
  out={}
  total={}
  @ds.each do |row|
    tot=@total[i]
    @ds.vectors.each do |f|
      out[f]||= {}
      total[f]||={}
      out[f][tot]||= 0
      total[f][tot]||=0
      out[f][tot]+= row[f]
      total[f][tot]+=1
    end
    i+=1
  end
  total.each do |f,var|
    var.each do |tot,v|
      out[f][tot]=out[f][tot].quo(total[f][tot])
    end
  end
  out
end

#item_difficulty_analysisObject

Returns a dataset with cases ordered by score and variables ordered by difficulty



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/statsample/reliability/scaleanalysis.rb', line 109

def item_difficulty_analysis
  dif={}
  @ds.vectors.each{|f| dif[f]=@ds[f].mean }
  dif_sort = dif.sort { |a,b| -(a[1]<=>b[1]) }
  scores_sort={}
  scores=@ds.vector_mean
  scores.each_index{ |i| scores_sort[i]=scores[i] }
  scores_sort=scores_sort.sort{|a,b| a[1]<=>b[1]}
  ds_new = Daru::DataFrame.new({}, order: ([:case,:score] + dif_sort.collect{|a,b| a.to_sym}))
  scores_sort.each do |i,score|
    row = [i, score]
    case_row = @ds.row[i].to_h
    dif_sort.each{ |variable,dif_value| row.push(case_row[variable]) }
    ds_new.add_row(row)
  end
  ds_new
end

#item_statisticsObject



100
101
102
103
104
105
# File 'lib/statsample/reliability/scaleanalysis.rb', line 100

def item_statistics
  @is||=@ds.vectors.to_a.inject({}) do |a,v|
    a[v]={:mean=>@ds[v].mean, :sds=>Math::sqrt(@cov_m.variance(v))}
    a
  end
end

#item_total_correlationObject

Adjusted R.P.B. for each item

Adjusted RPB(Point biserial-correlation) for each item



89
90
91
92
93
94
95
96
# File 'lib/statsample/reliability/scaleanalysis.rb', line 89

def item_total_correlation
  vecs = @ds.vectors.to_a
  @itc ||= vecs.inject({}) do |a,v|
    total=@ds.vector_sum(vecs - [v])
    a[v]=Statsample::Bivariate.pearson(@ds[v],total)
    a
  end
end

#mean_rpbObject



97
98
99
# File 'lib/statsample/reliability/scaleanalysis.rb', line 97

def mean_rpb
  Daru::Vector.new(item_total_correlation.values).mean
end

#report_building(builder) ⇒ Object

:nodoc:



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/statsample/reliability/scaleanalysis.rb', line 149

def report_building(builder) #:nodoc:
  builder.section(:name=>@name) do |s|
    
    if @dumped.size>0
      s.section(:name=>"Items with variance=0") do |s1|
        s.table(:name=>_("Summary for %s with all items") % @name) do |t|
          t.row [_("Items"), @ods.ncols]
          t.row [_("Sum mean"),     "%0.4f" % @o_total.mean]
          t.row [_("S.d. mean"),     "%0.4f" % @o_total.sd]
        end
        s.table(:name=>_("Deleted items"), :header=>['item','mean']) do |t|
          @dumped.each do |f|
            t.row(["#{@ods[f].name}(#{f})", "%0.5f" % @ods[f].mean])
          end
        end
        s.parse_element(Statsample::Graph::Histogram.new(@o_total, :name=>"Histogram (complete data) for %s" % @name)) if @summary_histogram
      end
    end
    
    
    s.table(:name=>_("Summary for %s") % @name) do |t|
      t.row [_("Valid Items"), @ds.ncols]
    
    t.row [_("Valid cases"), @valid_n]
    t.row [_("Sum mean"),     "%0.4f" % @mean]
    t.row [_("Sum sd"),       "%0.4f" % @sd  ]
#          t.row [_("Sum variance"), "%0.4f" % @variance]
    t.row [_("Sum median"),   @median]
    t.hr
    t.row [_("Item mean"),    "%0.4f" % @item_mean]
    t.row [_("Item sd"),    "%0.4f" % @item_sd]
    t.hr
    t.row [_("Skewness"),     "%0.4f" % @skew]
    t.row [_("Kurtosis"),     "%0.4f" % @kurtosis]
    t.hr
    t.row [_("Cronbach's alpha"), @alpha ? ("%0.4f" % @alpha) : "--"]
    t.row [_("Standarized Cronbach's alpha"), @alpha_standarized ? ("%0.4f" % @alpha_standarized) : "--" ]
    t.row [_("Mean rpb"), "%0.4f" % mean_rpb]
    
    t.row [_("Variances mean"),  "%g" % @variances_mean]
    t.row [_("Covariances mean") , "%g" % @covariances_mean]
    end
    
    if (@alpha)
      s.text _("Items for obtain alpha(0.8) : %d" % Statsample::Reliability::n_for_desired_reliability(@alpha, 0.8, @ds.ncols))
      s.text _("Items for obtain alpha(0.9) : %d" % Statsample::Reliability::n_for_desired_reliability(@alpha, 0.9, @ds.ncols))
    end
    
    
    sid=stats_if_deleted
    is=item_statistics
    itc=item_total_correlation
    
    s.table(:name=>_("Items report for %s") % @name, :header=>["item","mean","sd", "mean if deleted", "var if deleted", "sd if deleted"," item-total correl.", "alpha if deleted"]) do |t|
      @ds.vectors.each do |f|
        row=["#{@ds[f].name}(#{f})"]
        if is[f]
          row+=[sprintf("%0.5f",is[f][:mean]), sprintf("%0.5f", is[f][:sds])]
        else
          row+=["-","-"]
        end
        if sid[f]
          row+= [sprintf("%0.5f",sid[f][:mean]), sprintf("%0.5f",sid[f][:variance_sample]), sprintf("%0.5f",sid[f][:sds])]
        else
          row+=%w{- - -}
        end
        if itc[f]
          row+= [sprintf("%0.5f",itc[f])]
        else 
          row+=['-']
        end
        if sid[f] and !sid[f][:alpha].nil?
          row+=[sprintf("%0.5f",sid[f][:alpha])]
        else
          row+=["-"]
        end
        t.row row
      end # end each
    end # table
    s.parse_element(Statsample::Graph::Histogram.new(@total, :name=>"Histogram (valid data) for %s" % @name)) if @summary_histogram
  end # section
end

#stats_if_deletedObject



127
128
129
# File 'lib/statsample/reliability/scaleanalysis.rb', line 127

def stats_if_deleted
  @sif||=stats_if_deleted_intern
end

#stats_if_deleted_internObject

:nodoc:



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/statsample/reliability/scaleanalysis.rb', line 131

def stats_if_deleted_intern # :nodoc:
  return Hash.new if @ds.ncols == 1
  vecs = @ds.vectors.to_a
  vecs.inject({}) do |a,v|
    cov_2=@cov_m.submatrix(vecs - [v])
    #[email protected]
    #ds2.delete_vector(v)
    #total=ds2.vector_sum
    a[v]={}
    #a[v][:mean]=total.mean
    a[v][:mean]=@mean-item_statistics[v][:mean]
    a[v][:variance_sample]=cov_2.total_sum
    a[v][:sds]=Math::sqrt(a[v][:variance_sample])
    n=cov_2.row_size
    a[v][:alpha] = (n>=2) ? Statsample::Reliability.cronbach_alpha_from_covariance_matrix(cov_2) : nil
    a
  end
end