survival 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in survival.gemspec
4
+ gemspec
5
+
6
+ gem "rails", "~> 3.2.6"
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 TODO: Write your name
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,34 @@
1
+ # Survival
2
+
3
+ Functions related to survival analysis, such as Kaplan-Meier estimator of survival curves.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'survival'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install survival
18
+
19
+ ## Usage
20
+
21
+ To generate a Kaplan-Meier survival plot:
22
+
23
+ #survivals is an array of hashes. Each represents a sample, and must define :event (the event time) and :censored (boolean describing whether this sample is censored)
24
+ points = KaplanMeier.generate_plot_points(SurvivalSample.create_survival_objects(survivals))
25
+
26
+ #points is an array of [x,y] pairs for plotting. Use your favorite plotting library to plot the line graph.
27
+
28
+ ## Contributing
29
+
30
+ 1. Fork it
31
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
32
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
33
+ 4. Push to the branch (`git push origin my-new-feature`)
34
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rake/testtask'
4
+ require 'rdoc/task'
5
+
6
+ desc 'Default: run tests.'
7
+ task :default => :test
8
+
9
+ desc 'Run unit tests.'
10
+ Rake::TestTask.new(:test) do |t|
11
+ t.libs << 'lib'
12
+ t.libs << 'test'
13
+ t.pattern = 'test/**/*_test.rb'
14
+ t.verbose = true
15
+ end
16
+
17
+ desc 'Generate documentation'
18
+ Rake::RDocTask.new(:rdoc) do |rdoc|
19
+ rdoc.rdoc_dir = 'rdoc'
20
+ rdoc.title = 'Survival'
21
+ rdoc.options << '--line-numbers' << '--inline-source'
22
+ rdoc.rdoc_files.include('README.md')
23
+ rdoc.rdoc_files.include('lib/**/*.rb')
24
+ end
data/lib/survival.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'survival/version'
2
+ require 'survival/KaplanMeier'
3
+ require 'survival/SurvivalSample'
@@ -0,0 +1,56 @@
1
+ #########################################
2
+ #
3
+ # Creates a survival plot using the
4
+ # Kaplan-Meier method.
5
+ #
6
+ #########################################
7
+
8
+ class KaplanMeier
9
+
10
+ #Creates the x,y pairs for plotting a survival curve,
11
+ #using the Kaplan-Meier method.
12
+ def self.generate_plot_points(survivals)
13
+
14
+ bins = SurvivalSample.bin_survivals(survivals)
15
+
16
+ points = [[0,100]]
17
+
18
+ terms = Array.new
19
+ n = survivals.length #Number we are considering at this time point (total surviving minus censored)
20
+ prev = 100
21
+ bins.keys.sort.each do |t|
22
+
23
+ survs = bins[t]
24
+
25
+ #Update counts for this time point
26
+ d = 0 #Number that have died at this time point
27
+ survs.each do |s|
28
+ n = n-1
29
+
30
+ if not s.censored
31
+ d = d + 1
32
+ end
33
+ end
34
+
35
+ #Calculate the probability of survival for this time point
36
+ s_t = 1
37
+ terms.each do |term|
38
+ s_t = s_t * term
39
+ end
40
+
41
+ curr_term = (n - d).to_f / n
42
+ terms << curr_term
43
+
44
+ s_t = s_t * 100.0
45
+
46
+ #Add to plot points
47
+ points << [t, prev] #Horizontal line from previous point
48
+ points << [t, s_t] #Current point
49
+ prev = s_t
50
+
51
+ end
52
+
53
+ return points
54
+ end
55
+
56
+ end
@@ -0,0 +1,59 @@
1
+ #########################################
2
+ #
3
+ # Object for holding survival data.
4
+ #
5
+ # Roman Eisner
6
+ #
7
+ #########################################
8
+
9
+ class SurvivalSample
10
+
11
+ attr_accessor :censored, :event
12
+
13
+ def initialize(censored, event)
14
+ @censored = censored
15
+ @event = event
16
+ end
17
+
18
+ def to_s
19
+ "Survival: {Event: #{@event}, Censored: #{@censored}}"
20
+ end
21
+
22
+ #Sort method:
23
+ def <=>(o)
24
+
25
+ if self.event != o.event
26
+ return self.event <=> o.event
27
+ else
28
+ if (self.censored == o.censored)
29
+ return 0
30
+ elsif self.censored
31
+ return 1
32
+ else
33
+ return -1
34
+ end
35
+ end
36
+
37
+ end
38
+
39
+ #Takes an array of Survival objects, and returns a binned hash.
40
+ def SurvivalSample.bin_survivals(survs)
41
+ bins = Hash.new
42
+
43
+ survs.each do |s|
44
+ bins[s.event] ||= Array.new
45
+
46
+ bins[s.event] << s
47
+ end
48
+
49
+ return bins
50
+ end
51
+
52
+ #Takes an array of hashes, each has must have two keys:
53
+ # :event => The event time
54
+ # :censored => A boolean, true if this patient has been right-censored.
55
+ def SurvivalSample.create_survival_objects(surv_array)
56
+ return surv_array.map { |s| SurvivalSample.new(s[:censored], s[:event]) }
57
+ end
58
+
59
+ end
@@ -0,0 +1,3 @@
1
+ module Survival
2
+ VERSION = "0.0.1"
3
+ end
data/survival.gemspec ADDED
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'survival/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "survival"
8
+ gem.version = Survival::VERSION
9
+ gem.authors = ["Roman Eisner"]
10
+ gem.email = ["ithmatic@gmail.com"]
11
+ gem.description = %q{A gem that provides survival analysis functionality}
12
+ gem.summary = %q{Kaplan-Meier Estimation}
13
+ gem.homepage = "https://github.com/reisner/survival"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ end
@@ -0,0 +1,21 @@
1
+ require 'test_helper'
2
+
3
+ class SurvivalTest < ActiveSupport::TestCase
4
+
5
+ @@survivals = [{:event => 3, :censored => false}, {:event => 4, :censored => true}]
6
+
7
+ test 'km plot' do
8
+ p = KaplanMeier.generate_plot_points(SurvivalSample.create_survival_objects(@@survivals))
9
+ assert_equal [[0, 100], [3, 100], [3, 100.0], [4, 100.0], [4, 0.0]], p
10
+ end
11
+
12
+ test 'survival_sample array' do
13
+ assert_equal 2, SurvivalSample.create_survival_objects(@@survivals).length
14
+ end
15
+
16
+ test 'survival_sample new' do
17
+ assert_equal false, SurvivalSample.new(false, 34).censored
18
+ assert_equal 34, SurvivalSample.new(false, 34).event
19
+ end
20
+
21
+ end
@@ -0,0 +1,5 @@
1
+ require 'active_support'
2
+ require 'test/unit'
3
+ require 'survival'
4
+
5
+ ENV["RAILS_ENV"] = "test"
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: survival
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Roman Eisner
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-23 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: A gem that provides survival analysis functionality
15
+ email:
16
+ - ithmatic@gmail.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - .gitignore
22
+ - Gemfile
23
+ - LICENSE.txt
24
+ - README.md
25
+ - Rakefile
26
+ - lib/survival.rb
27
+ - lib/survival/KaplanMeier.rb
28
+ - lib/survival/SurvivalSample.rb
29
+ - lib/survival/version.rb
30
+ - survival.gemspec
31
+ - test/survival_test.rb
32
+ - test/test_helper.rb
33
+ homepage: https://github.com/reisner/survival
34
+ licenses: []
35
+ post_install_message:
36
+ rdoc_options: []
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ! '>='
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ requirements: []
52
+ rubyforge_project:
53
+ rubygems_version: 1.8.23
54
+ signing_key:
55
+ specification_version: 3
56
+ summary: Kaplan-Meier Estimation
57
+ test_files:
58
+ - test/survival_test.rb
59
+ - test/test_helper.rb