module Statsample module Reliability class << self # Calculate Chonbach's alpha for a given dataset. # only uses tuples without missing data def cronbach_alpha(ods) ds=ods.dup_only_valid n_items=ds.fields.size s2_items=ds.vectors.inject(0) {|ac,v| ac+v[1].variance } total=ds.vector_sum (n_items.quo(n_items-1)) * (1-(s2_items.quo(total.variance))) end # Calculate Chonbach's alpha for a given dataset # using standarized values for every vector. # Only uses tuples without missing data def cronbach_alpha_standarized(ods) ds=ods.dup_only_valid.fields.inject({}){|a,f| a[f]=ods[f].standarized; a }.to_dataset cronbach_alpha(ds) end def cronbach_alpha_from_n_s2_cov(n,s2,cov) (n.quo(n-1)) * (1-(s2.quo(s2+(n-1)*cov))) end # Returns n necessary to obtain specific alpha # given variance and covariance mean of items def n_for_desired_alpha(alpha,s2,cov) # Start with a regular test : 50 items min=2 max=1000 n=50 prev_n=0 epsilon=0.0001 dif=1000 c_a=cronbach_alpha_from_n_s2_cov(n,s2,cov) dif=c_a - alpha while(dif.abs>epsilon and n!=prev_n) prev_n=n if dif<0 min=n n=(n+(max-min).quo(2)).to_i else max=n n=(n-(max-min).quo(2)).to_i end c_a=cronbach_alpha_from_n_s2_cov(n,s2,cov) dif=c_a - alpha #puts "#{n} , #{c_a}" end n end # First derivative for alfa # Parameters # n: Number of items # sx: mean of variances # sxy: mean of covariances def alpha_first_derivative(n,sx,sxy) (sxy*(sx-sxy)).quo(((sxy*(n-1))+sx)**2) end # Second derivative for alfa # Parameters # n: Number of items # sx: mean of variances # sxy: mean of covariances def alfa_second_derivative(n,sx,sxy) (2*(sxy**2)*(sxy-sx)).quo(((sxy*(n-1))+sx)**3) end end class ItemCharacteristicCurve attr_reader :totals, :counts, :vector_total def initialize (ds, vector_total=nil) vector_total||=ds.vector_sum raise ArgumentError, "Total size != Dataset size" if vector_total.size!=ds.cases @vector_total=vector_total @ds=ds @totals={} @counts=@ds.fields.inject({}) {|a,v| a[v]={};a} process end def process i=0 @ds.each do |row| tot=@vector_total[i] @totals[tot]||=0 @totals[tot]+=1 @ds.fields.each do |f| item=row[f].to_s @counts[f][tot]||={} @counts[f][tot][item]||=0 @counts[f][tot][item] += 1 end i+=1 end end # Return a hash with p for each different value on a vector def curve_field(field, item) out={} item=item.to_s @totals.each do |value,n| count_value= @counts[field][value][item].nil? ? 0 : @counts[field][value][item] out[value]=count_value.quo(n) end out end # def end # self end # Reliability end # Statsample require 'statsample/reliability/scaleanalysis.rb' require 'statsample/reliability/multiscaleanalysis.rb'