Module: Charty::Statistics

Defined in:
lib/charty/statistics.rb

Class Method Summary collapse

Class Method Details

.bootstrap(vector, n_boot: 2000, func: :mean, units: nil, random: nil) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/charty/statistics.rb', line 38

def self.bootstrap(vector, n_boot: 2000, func: :mean, units: nil, random: nil)
  n = vector.size
  random = Charty::Plotters::RandomSupport.check_random(random)
  func = Charty::Plotters::EstimationSupport.check_estimator(func)

  if units
    return structured_bootstrap(vector, n_boot, units, func, random)
  end

  if defined?(Pandas::Series) || defined?(Numpy::NDArray)
    boot_dist = bootstrap_optimized_for_pycall(vector, n_boot, random, func)
    return boot_dist if boot_dist
  end

  boot_dist = Array.new(n_boot) do |i|
    resampler = Array.new(n) { random.rand(n) }

    w ||= vector.values_at(*resampler)

    case func
    when :mean
      mean(w)
    end
  end

  boot_dist
end

.bootstrap_ci(*vectors, width, n_boot: 2000, func: :mean, units: nil, random: nil) ⇒ Object



95
96
97
98
99
100
101
102
103
# File 'lib/charty/statistics.rb', line 95

def self.bootstrap_ci(*vectors, width, n_boot: 2000, func: :mean, units: nil, random: nil)
  boot = bootstrap(*vectors, n_boot: n_boot, func: func, units: units, random: random)
  q = [50 - width / 2, 50 + width / 2]
  if boot.respond_to?(:percentile)
    boot.percentile(q)
  else
    percentile(boot, q)
  end
end

.percentile(a, q) ⇒ Object

TODO: optimize with introselect algorithm



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/charty/statistics.rb', line 106

def self.percentile(a, q)
  return mean(a) if a.size == 0

  a = a.sort
  n = a.size
  q.map do |x|
    x = (n-1) * (x / 100.0)
    i = x.floor
    if i == x
      a[i]
    else
      t = x - i
      (1-t)*a[i] + t*a[i+1]
    end
  end
end