Giter Club home page Giter Club logo

descriptive_statistics's Introduction

Descriptive Statistics

Gem Version Build Status

Overview

This gem adds methods to the Enumerable module to allow easy calculation of basic descriptive statistics of Numeric sample data in collections that have included Enumerable such as Array, Hash, Set, and Range. The statistics that can be calculated are:

  • Number
  • Sum
  • Mean
  • Median
  • Mode
  • Variance
  • Standard Deviation
  • Percentile
  • Percentile Rank
  • Descriptive Statistics
  • Quartiles

When requiring DescriptiveStatistics, the Enumerable module is monkey patched so that the statistical methods are available on any instance of a class that has included Enumerable. For example with an Array:

require 'descriptive_statistics'
data = [2,6,9,3,5,1,8,3,6,9,2]
# => [2, 6, 9, 3, 5, 1, 8, 3, 6, 9, 2]
data.number
# => 11.0
data.sum
# => 54.0
data.mean
# => 4.909090909090909
data.median
# => 5.0
data.variance
# => 7.7190082644628095
data.standard_deviation
# => 2.778310325442932
data.percentile(30)
# => 3.0
data.percentile(70)
# => 6.0
data.percentile_rank(8)
# => 81.81818181818183
data.mode
# => 2
data.range
# => 8
data.descriptive_statistics
# => {:number=>11.0,
  :sum=>54,
  :variance=>7.7190082644628095,
  :standard_deviation=>2.778310325442932,
  :min=>1,
  :max=>9,
  :mean=>4.909090909090909,
  :mode=>2,
  :median=>5.0,
  :range=>8.0,
  :q1=>2.5,
  :q2=>5.0,
  :q3=>7.0}

and with other types of objects:

require 'set'
require 'descriptive_statistics'
{:a=>1, :b=>2, :c=>3, :d=>4, :e=>5}.mean #Hash
# => 3.0
Set.new([1,2,3,4,5]).mean #Set
# => 3.0
(1..5).mean #Range
# => 3.0

including instances of your own classes, when an each method is provided that creates an Enumerator over the sample data to be operated upon:

class Foo
  include Enumerable
  attr_accessor :bar, :baz, :bat

  def each
    [@bar, @baz, @bat].each
  end
end

foo = Foo.new
foo.bar = 1
foo.baz = 2
foo.bat = 3
foo.mean
# => 2.0

or:

class Foo
  include Enumerable
  attr_accessor :bar, :baz, :bat

  def each
    Enumerator.new do |y|
      y << @bar
      y << @baz
      y << @bat
    end
  end
end

foo = Foo.new
foo.bar = 1
foo.baz = 2
foo.bat = 3
foo.mean
# => 2.0

and even Structs:

Scores = Struct.new(:sally, :john, :peter)
bowling = Scores.new
bowling.sally = 203
bowling.john = 134
bowling.peter = 233
bowling.mean
# => 190.0

All methods optionally take blocks that operate on object values. For example:

require 'descriptive_statistics'
LineItem = Struct.new(:price, :quantity)
cart = [ LineItem.new(2.50, 2), LineItem.new(5.10, 9), LineItem.new(4.00, 5) ]
total_items = cart.sum(&:quantity)
# => 16
total_price = cart.sum{ |i| i.price * i.quantity }
# => 70.9

Note that you can extend DescriptiveStatistics on individual objects by requiring DescriptiveStatistics safely, thus avoiding the monkey patch. For example:

require 'descriptive_statistics/safe'
data = [2,6,9,3,5,1,8,3,6,9,2]
# => [2, 6, 9, 3, 5, 1, 8, 3, 6, 9, 2]
data.extend(DescriptiveStatistics)
# => [2, 6, 9, 3, 5, 1, 8, 3, 6, 9, 2]
data.number
# => 11.0
data.sum
# => 54

Or, if you prefer leaving your collection pristine, you can create a Stats object that references your collection:

require 'descriptive_statistics/safe'
data = [1, 2, 3, 4, 5, 1]
# => [1, 2, 3, 4, 5, 1]
stats = DescriptiveStatistics::Stats.new(data)
# => [1, 2, 3, 4, 5, 1]
stats.class
# => DescriptiveStatistics::Stats
stats.mean
# => 2.6666666666666665
stats.median
# => 2.5
stats.mode
# => 1
data << 2
# => [1, 2, 3, 4, 5, 1, 2]
data << 2
# => [1, 2, 3, 4, 5, 1, 2, 2]
stats.mode
# => 2

Or you call the statistical methods directly:

require 'descriptive_statistics/safe'
# => true
DescriptiveStatistics.mean([1,2,3,4,5])
# => 3.0
DescriptiveStatistics.mode([1,2,3,4,5])
# => 1
DescriptiveStatistics.variance([1,2,3,4,5])
# => 2.0

Or you can use Refinements (available in Ruby >= 2.1) to augment any class that mixes in the Enumerable module. Refinements are lexically scoped and so the statistical methods will only be available in the file where they are used. Note that the lexical scope can be limited to a Class or Module, but only applies to code in that file. This approach provides a great deal of protection against introducing conflicting modifications to Enumerable while retaining the convenience of the monkey patch approach.

require 'descriptive_statistics/refinement'

class SomeServiceClass
  using DescriptiveStatistics::Refinement.new(Array)

  def self.calculate_something(array)
    array.standard_deviation
  end
end

[1,2,3].standard_deviation
# => NoMethodError: undefined method `standard_deviation' for [1, 2, 3]:Array

SomeServiceClass.calculate_something([1,2,3])
#=> 0.816496580927726

Ruby on Rails

To use DescriptiveStatistics with Ruby on Rails add DescriptiveStatistics to your Gemfile, requiring the safe extension.

source 'https://rubygems.org'

gem 'rails', '4.1.7'
gem 'descriptive_statistics', '~> 2.4.0', :require => 'descriptive_statistics/safe'

Then after a bundle install, you can extend DescriptiveStatistics on an individual collection and call the statistical methods as needed.

users = User.all.extend(DescriptiveStatistics)
mean_age = users.mean(&:age) # => 19.428571428571427
mean_age_in_dog_years = users.mean { |user| user.age / 7.0 } # => 2.7755102040816326

Notes

  • All methods return a Float object except for mode, which will return a Numeric object from the collection. mode will always return nil for empty collections.
  • All methods return nil when the collection is empty, except for number, which returns 0.0. This is a different behavior than ActiveSupport's Enumerable monkey patch of sum, which by deafult returns the Fixnum 0 for empty collections. You can change this behavior by specifying the default value returned for empty collections all at once:

require 'descriptive_statistics' [].mean

=> nil

[].sum

=> nil

DescriptiveStatistics.empty_collection_default_value = 0.0

=> 0.0

[].mean

=> 0.0

[].sum

=> 0.0

or one at a time:
```ruby
require 'descriptive_statistics'
[].mean
# => nil
[].sum
# => nil
DescriptiveStatistics.sum_empty_collection_default_value = 0.0
# => 0.0
[].mean
# => nil
[].sum
# => 0.0
DescriptiveStatistics.mean_empty_collection_default_value = 0.0
# => 0.0
[].mean
# => 0.0
[].sum
# => 0.0
  • The scope of this gem covers Descriptive Statistics and not Inferential Statistics. From wikipedia:

    Descriptive statistics is the discipline of quantitatively describing the main features of a collection of information, or the quantitative description itself. Descriptive statistics are distinguished from inferential statistics, in that descriptive statistics aim to summarize a sample, rather than use the data to learn about the population that the sample of data is thought to represent.

    Thus, all statistics calculated herein describe only the values in the collection. Where this makes a practical difference is in the calculation of variance (and thus the standard deviation which is derived from variance). We use the population variance to calculate the variance of the values in the collection. If the values in your collection represent a sampling from a larger population of values, and your goal is to estimate the population variance from your sample, you should use the inferential statistic, sample variance. However, the calculation of the sample variance is outside the scope of this gem's functionality.

Ports

Javascript

Python

Go

Elixir

Clojure

License

Copyright (c) 2010-2014 Derrick Parkhurst ([email protected]), Gregory Brown ([email protected]), Daniel Farrell ([email protected]), Graham Malmgren, Guy Shechter, Charlie Egan ([email protected])

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

descriptive_statistics's People

Contributors

charlieegan3 avatar dejan avatar grosser avatar lawrencejones avatar nickmcdonnough avatar practicingruby avatar pusewicz avatar simplyknownasg avatar thirtysixthspan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

descriptive_statistics's Issues

rake db:create fails

Looks like there's an overriding method which causes this to fail.

Rails 4.1.4 and descriptive_statistics 2.5.1

Compatibility Inquiry: descriptive_statistics 2.5.1 with Ruby 3.3.0

Hi,

I'm seeking confirmation regarding the compatibility of the descriptive_statistics 2.5.1 with the recently released Ruby 3.3.0 (December 25, 2023).

While I reviewed the gem's documentation on RubyGems and table mentioned it only specifies a minimum required Ruby version of > 0. Unfortunately, I haven't found any explicit confirmation on compatibility with newer versions like 3.3.0.

Given your expertise in this area, could you offer any insights or leads on this matter? Any information you can provide would be greatly appreciated.

Thank you for your time and assistance!

why rename not pull-request?

As a user I'm confused by your renaming and republication of the descriptive-statistics gem. Why not collaborate on that instead of creating a new gem and repo? Did you try contacting @jtescher ?

What's the difference between this and that? It'd be useful to have an explanation at the top or bottom of the readme about why you've forked it and what the difference in vision is.

Thanks!

Median of an array with only one element fails

Calculating the median of an array with only a single element fails. The median code uses percentile(50) and that crashes if there are not al least two elements.

I know that it makes little sense to calculate the median of a single element, however, I use the desctiptive_statistics gem to do batch processing of large amounts of data and process arrays with lengths from 1 to n.

While I can handle that case in my code, I think that others would also benefit if median would work for one element.

is this gem still active?

Hi, I'm looking at the last commit and it was a long time ago, is this project still on use or not?

thanks

Return value for an empty set

Hi Derrick,

Thank you for an awesome gem!

Zero is only the identity under sum, i.e. for all xs: sum(xs) = sum(xs + [0]).

Therefore, sum([] + [0]) = sum([]). Since [] + [0] = [0], it follows that sum([0]) = sum([]) = 0, so sum([]) should always return 0.

For all the other statistics, the opposite is true: f(xs + [0]) != f(xs), so they should not return 0.

Would you like me to open a pull request?

PG:Error when gem is included in Gemfile

Rails 3.2.12
Gemfile line:
gem 'descriptive_statistics', :github =>'thirtysixthspan/descriptive_statistics'

When I include this gem in my gemfile I am unable to run my tests due to the error below. If I remove the gem from my Gemfile the error is fixed.

rake db:test:load

PG::Error: ERROR:  syntax error at or near "["
LINE 1: CREATE DATABASE "xxxxx_test"[:encoding, "utf-8", :adap...
                                    ^
: CREATE DATABASE "xxxxx_test"[:encoding, "utf-8", :adapter, "postgresql", :host, "localhost", :pool, 5, :password, "qwerty", :username, "xxxxx", :database, "xxxxx_test"]

/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.12/lib/active_record/connection_adapters/postgresql_adapter.rb:652:in `async_exec'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.12/lib/active_record/connection_adapters/postgresql_adapter.rb:652:in `block in execute'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract_adapter.rb:280:in `block in log'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-3.2.12/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract_adapter.rb:275:in `log'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.12/lib/active_record/connection_adapters/postgresql_adapter.rb:651:in `execute'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.12/lib/active_record/connection_adapters/postgresql_adapter.rb:766:in `create_database'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.12/lib/active_record/railties/databases.rake:130:in `rescue in create_database'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.12/lib/active_record/railties/databases.rake:74:in `create_database'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.12/lib/active_record/railties/databases.rake:518:in `block (3 levels) in <top (required)>'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/rake-10.0.3/lib/rake/task.rb:228:in `call'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/rake-10.0.3/lib/rake/task.rb:228:in `block in execute'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/rake-10.0.3/lib/rake/task.rb:223:in `each'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/rake-10.0.3/lib/rake/task.rb:223:in `execute'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/rake-10.0.3/lib/rake/task.rb:166:in `block in invoke_with_call_chain'
/home/fkumro/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:211:in `mon_synchronize'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/rake-10.0.3/lib/rake/task.rb:159:in `invoke_with_call_chain'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/rake-10.0.3/lib/rake/task.rb:187:in `block in invoke_prerequisites'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/rake-10.0.3/lib/rake/task.rb:185:in `each'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/rake-10.0.3/lib/rake/task.rb:185:in `invoke_prerequisites'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/rake-10.0.3/lib/rake/task.rb:165:in `block in invoke_with_call_chain'
/home/fkumro/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:211:in `mon_synchronize'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/rake-10.0.3/lib/rake/task.rb:159:in `invoke_with_call_chain'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/rake-10.0.3/lib/rake/task.rb:152:in `invoke'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/rake-10.0.3/lib/rake/application.rb:143:in `invoke_task'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/rake-10.0.3/lib/rake/application.rb:101:in `block (2 levels) in top_level'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/rake-10.0.3/lib/rake/application.rb:101:in `each'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/rake-10.0.3/lib/rake/application.rb:101:in `block in top_level'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/rake-10.0.3/lib/rake/application.rb:110:in `run_with_threads'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/rake-10.0.3/lib/rake/application.rb:95:in `top_level'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/rake-10.0.3/lib/rake/application.rb:73:in `block in run'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/rake-10.0.3/lib/rake/application.rb:160:in `standard_exception_handling'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/rake-10.0.3/lib/rake/application.rb:70:in `run'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/gems/rake-10.0.3/bin/rake:33:in `<top (required)>'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/bin/rake:23:in `load'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/bin/rake:23:in `<main>'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/bin/ruby_noexec_wrapper:14:in `eval'
/home/fkumro/.rvm/gems/ruby-2.0.0-p247/bin/ruby_noexec_wrapper:14:in `<main>'

Any idea if there is a work around for this?

Max and Min Gives Misleading Data

require 'descriptive_statistics'
hash = {:a=>2,:b=>6,:c=>9,:d=>3,:e=>5,:f=>1,:g=>8,:h=>3,:i=>6,:j=>9,:k=>2}
hash.min
#=> [:a, 2]
hash.min_by { | key, value | value }
#=> [:f, 1]

hash.max
#=> [:k, 2]
hash.max_by { | key, value | value }
#=> [:c, 9]

This gem is using the native "Ruby" max and min functions, which don't really work well for Hashes (it defaults to finding the maximum and minimum keys, which is a fairly useless piece of trivia...most of the time, we don't care about alphabetical order). While you can get the correct answers by using the max_by or min_by methods that is also within native Ruby, this little "feature" can get pretty annoying when you decide to use this Ruby gem's descriptive_statistics method.

hash.descriptive_statistics
#=>
{:number=>11.0, 
:sum=>54.0, 
:variance=>7.7190082644628095, 
:standard_deviation=>2.778310325442932, 
:min=>[:a, 2],
:max=>[:k, 2],
:mean=>4.909090909090909,
:mode=>2,
:median=>5.0,
:range=>8.0,
:q1=>2.5,
:q2=>5.0,
:q3=>7.0}

I don't really know of a good way to fix this annoyance, which is why I am reporting this issue to you. At the very least, having this issue here is a great way to prevent future people from getting annoyed.

anyone thought to ignore nulls, as an option

Often I have holes in my data, and I want to get some stats but ignore nulls.
example:
data = [1, 2, 3, 4, 5, nil] # => [1, 2, 3, 4, 5, nil]
stats = DescriptiveStatistics::Stats.new(data)
stats.mean # => 2.5

because the nil is treated like a zero. If instead this "data hole" is ignored, the mean should be 3.0, as in
stats = DescriptiveStatistics::Stats.new(data.compact)
stats.mean # => 3.0

Has there been any discussion of an optional parameter to ignore nulls? Perhaps something like:
stats = DescriptiveStatistics::State.new(data, ignore_nulls=true)

(Object doesn't support #inspect) caused by descriptive_statistics

I have a Portfolio model, which has_many AssetWeight models. Upon inclusion of the descriptive_statistics gem, I get a strange error, (Object doesn't support #inspect)

Models:

class Portfolio < ActiveRecord::Base
  belongs_to :investment_case
  has_many :asset_weights, :dependent => :destroy
  attr_accessible :name
end

class AssetWeight < ActiveRecord::Base
  belongs_to :portfolios
  belongs_to :asset
  attr_accessible :name, :weight
end

Code to cause the error

1.9.3-p392 :001 > p = Portfolio.first
1.9.3-p392 :002 > p.asset_weights
(Object doesn't support #inspect)
 => 

It worked fine before adding the gem to my Gemfile. Removing it after stopped the problem also.

Variance & STDEV => population not sample

The variance & standard deviation methods return the population var/st. deviation, not the sample method which is usually what one would want and what users would be likely to expect.

variance.rb ought to read:

module DescriptiveStatistics
  def variance
    mean = self.mean
    self.map{ |sample| (mean - sample) ** 2 }.inject(:+) / (self.number - 1)
  end
end

I've submitted a pull request for this change

#sum method breaks with Ruby 2.4

Rails does some gymnastics to use the Enumerable#sum method built into Ruby 2.4+, and it falls back to the ActiveSupport Enumerable#sum method to handle situations in which the Ruby method doesn't handle it, such as an Array of Strings. Unfortunately, DescriptiveStatistics' #sum method gets in the way and breaks things when the Array is empty.

Using Ruby 2.4.2 and Rails 5.1.4 with descriptive_statistics 2.5.1:

>> [].sum
#> NoMethodError: undefined method `each' for nil:NilClass

See this post on StackOverflow for details.

Missing tests for .gem file

Hey ,
I'm planning to package descriptive_statistics to be available in debain.Unfortunately the gem file downloaded from rubygems.org does not come with tests. Can you include tests to be available for the gem uploaded in rubygems.org ?

Gem is inconsistent with Rails methods which lead to really bad behavior.

Defining all the DescriptiveStatistics methods on enumerable without namespacing whatsoever can lead to incompatibility with the Rails framework. Given that it is the most used framework in the community, I think this can lead to really nasty bugs.

For instance Rails already define a method sum on Enumerable, which is:

# File activesupport/lib/active_support/core_ext/enumerable.rb, line 20
def sum(identity = 0, &block)
  if block_given?
    map(&block).sum(identity)
  else
    inject { |sum, element| sum + element } || identity
  end
end

and DescriptiveStatistics#sum is:

  def sum(collection = self, &block)
    values = Support::convert(collection, &block)
    return DescriptiveStatistics.sum_empty_collection_default_value if values.empty?

    return values.reduce(:+)
  end

As you can see the behaviour AND the signature is not the same.
Most notably, in rails:

[].sum # -> 0
[].sum(3) # -> 3

in this gem:

[].sum # -> nil
[].sum(3) # -> NoMethodError: undefined method `each' for 3:Fixnum

the 0 becoming nil is the most concerning for those using both Rails and this gem, since the bug can go undetected for quite a while.

In my opinion, the best approach would be either to namespace/prefix the methods, (or instead of including it as a mixin in Enumerable, having module functions but that's way more restrictive).

What do you think of it? what do you think would be the best solution to it?

requiring fails in Ruby 1.9.3

You'll get the following stack on a require:

/Users/doug/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/descriptive_statistics-2.3.0/lib/descriptive_statistics/class_methods.rb:24:in `define_method': bind argument must be a subclass of DescriptiveStatistics (TypeError)
    from /Users/doug/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/descriptive_statistics-2.3.0/lib/descriptive_statistics/class_methods.rb:24:in `block in singletonclass'
    from /Users/doug/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/descriptive_statistics-2.3.0/lib/descriptive_statistics/class_methods.rb:23:in `each'
    from /Users/doug/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/descriptive_statistics-2.3.0/lib/descriptive_statistics/class_methods.rb:23:in `singletonclass'
    from /Users/doug/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/descriptive_statistics-2.3.0/lib/descriptive_statistics/class_methods.rb:3:in `<module:DescriptiveStatistics>'
    from /Users/doug/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/descriptive_statistics-2.3.0/lib/descriptive_statistics/class_methods.rb:1:in `<top (required)>'
    from /Users/doug/.rbenv/versions/1.9.3-p448/lib/ruby/site_ruby/1.9.1/rubygems/core_ext/kernel_require.rb:54:in `require'
    from /Users/doug/.rbenv/versions/1.9.3-p448/lib/ruby/site_ruby/1.9.1/rubygems/core_ext/kernel_require.rb:54:in `require'
    from /Users/doug/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/descriptive_statistics-2.3.0/lib/descriptive_statistics/safe.rb:14:in `<top (required)>'
    from /Users/doug/.rbenv/versions/1.9.3-p448/lib/ruby/site_ruby/1.9.1/rubygems/core_ext/kernel_require.rb:54:in `require'
    from /Users/doug/.rbenv/versions/1.9.3-p448/lib/ruby/site_ruby/1.9.1/rubygems/core_ext/kernel_require.rb:54:in `require'
    from /Users/doug/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/descriptive_statistics-2.3.0/lib/descriptive_statistics.rb:1:in `<top (required)>'
    from /Users/doug/.rbenv/versions/1.9.3-p448/lib/ruby/site_ruby/1.9.1/rubygems/core_ext/kernel_require.rb:128:in `require'
    from /Users/doug/.rbenv/versions/1.9.3-p448/lib/ruby/site_ruby/1.9.1/rubygems/core_ext/kernel_require.rb:128:in `rescue in require'
    from /Users/doug/.rbenv/versions/1.9.3-p448/lib/ruby/site_ruby/1.9.1/rubygems/core_ext/kernel_require.rb:39:in `require'
    from ./graphite_tools.rb:6:in `<main>'

I upgraded to Ruby 2.0 and it worked fine.

Interested in a patch to make this library less invasive?

Hi,

If you're interested in a patch that will make this library a little bit less dependent on direct monkey patching, I'd be happy to prepare one.

The steps to build it would basically be this:

  1. Move all your method definitions into a DescriptiveStatistics module rather than directly into Enumerable
  2. Add to lib/descriptive_statistics.rb something like module Enumerable; include DescriptiveStatistics; end
  3. Add a file called lib/descriptive_statistics/safe.rb which will require all the files but NOT mix DescriptiveStatistics into Enumerable.

This will not change the behavior in the default use case of the library, it will only improve the architecture somewhat and give a few more options as to how these features can be used. If this sounds useful to you, let me know and I'll prepare a pull request.

Overriding Array Sum method causes issues with active support's Enumerable Sum method.

If an enumerable object contains a block or a any sort of non numerical values, this could cause unexpected behaviour.

Before Adding Gem
{:test => 1}.sum{|k,v| "#{k} #{v}"} # "test 1"

After adding Gem
{:test => 1}.sum{|k,v| "#{k} #{v}"} # [:test, 1]

Active Support is a very popular gem. It might be wise to implement it similar to active support. I can provide a patch if needed.

mean code

I think there is a problem with the code when using integers
try calculating mean of [3,4]

problem is also shown below
irb(main):008:0> 7/2
=> 3
irb(main):009:0> 7.to_f/2
=> 3.5

i did not verify it with your gem as I do not use it but I might be right
if not, sorry :-)

cannot calculate standard_deviation without global monkey patch

Following the example for extending an individual object, it falls over when you try and calculate standard_deviation. Adding the global monkey path works around the problem (but I don't want a global monkey patch):

$ irb
irb(main):001:0> require 'descriptive_statistics/safe'
=> true
irb(main):002:0> data = [2,6,9,3,5,1,8,3,6,9,2]
=> [2, 6, 9, 3, 5, 1, 8, 3, 6, 9, 2]
irb(main):003:0> data.extend(DescriptiveStatistics)
=> [2, 6, 9, 3, 5, 1, 8, 3, 6, 9, 2]
irb(main):004:0> data.number
=> 11.0
irb(main):005:0> data.sum
=> 54
irb(main):006:0> data.standard_deviation
NoMethodError: undefined method `sum' for #<Array:0x007fea6799c970>
        from /home/ianh/.gem/ruby/2.1.2/gems/descriptive_statistics-1.1.5/lib/descriptive_statistics/variance.rb:4:in `variance'
        from /home/ianh/.gem/ruby/2.1.2/gems/descriptive_statistics-1.1.5/lib/descriptive_statistics/standard_deviation.rb:3:in `standard_deviation'
        from (irb):6
        from /home/ianh/.rubies/2.1.2/bin/irb:11:in `<main>'
irb(main):007:0> require 'descriptive_statistics'
=> true
irb(main):008:0> data.standard_deviation
=> 2.778310325442932
irb(main):009:0> 

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.