class SimpleTimeSeries
Constants
- DEBUG
- VERSION
Attributes
attribs[RW]
data_vars[RW]
time_vars[RW]
Public Class Methods
new(opts)
click to toggle source
# File lib/simple_time_series/simple_time_series.rb, line 7 def initialize(opts) @time_vars = opts[:time_vars] @data_vars = opts[:data_vars] @attribs = opts[:attribs] define_data_methods_and_set_values define_time_methods_and_set_values end
Public Instance Methods
current(what, opts={})
click to toggle source
# File lib/simple_time_series/simple_time_series.rb, line 67 def current(what, opts={}) puts "#current called with #{what} and #{opts}" if DEBUG send(what.to_sym, opts) end
data_array(*data_var_names, opts)
click to toggle source
# File lib/simple_time_series/simple_time_series.rb, line 45 def data_array(*data_var_names, opts) err_msg = "The last parameter passed to #data_array must be a hash of start/end values.\n" err_msg += "Example: {:start => 'Tuesday', :end => '2014-01-06'}\n" err_msg += "If you want to use all observations, you can pass a blank hash, like {}\n" raise err_msg unless opts data_arr = [] Array(data_var_names).each do |name| puts "Looping through data_var_names inside data_array with #{name}" if DEBUG puts "Calling find(#{name}, #{opts[:start]}, #{opts[:end]}, #{opts})" if DEBUG data_arr << find(name, opts[:start], opts[:end], opts) end if opts[:prepend_names] if opts[:prepend_names].is_a? Array data_arr = data_arr.each_with_index.map { |var, idx| var.dup.unshift(opts[:prepend_names][idx]) } else data_arr = data_arr.each_with_index.map { |var, idx| var.dup.unshift(data_var_names[idx]) } end end data_arr end
find(what, date, end_date=nil, opts={})
click to toggle source
# File lib/simple_time_series/simple_time_series.rb, line 23 def find(what, date, end_date=nil, opts={}) puts "Calling send(#{what}_on, #{date}, #{end_date}, #{opts})" if DEBUG send((what + '_on').to_sym, date, end_date, opts) end
find_plus_label(what, date, end_date=nil)
click to toggle source
# File lib/simple_time_series/simple_time_series.rb, line 28 def find_plus_label(what, date, end_date=nil) find(what, date, end_date).dup.unshift(what) end
index_of_date_value(date)
click to toggle source
# File lib/simple_time_series/simple_time_series.rb, line 72 def index_of_date_value(date) time_vars.each do |tv_key, tv_val| return tv_val.index(date) if tv_val.include?(date) end nil end
method_missing(meth, *args, &block)
click to toggle source
Calls superclass method
# File lib/simple_time_series/simple_time_series.rb, line 15 def method_missing(meth, *args, &block) begin attribs[args[0]][meth] rescue super end end
new_data_var(var, vals)
click to toggle source
# File lib/simple_time_series/simple_time_series.rb, line 92 def new_data_var(var, vals) define_getter_and_setter(var) self.class.class_eval do define_method("#{var}_subset") do |first, last=first| start_idx = index_of_date_value(first) last_idx = index_of_date_value(last) (start_idx && last_idx) ? eval(var)[start_idx..last_idx] : nil end define_method("#{var}_subset_set") do |first, last, val_arr| start_idx = index_of_date_value(first) last_idx = index_of_date_value(last) if (start_idx && last_idx) eval(var)[start_idx..last_idx] = val_arr else raise "Could not run #{var}_subset with values #{val_arr}" end end define_method("#{var}_diff") do |first=nil, last=nil| # should work only on numeric data # this could be made more efficient by caching the full array and/or calculating only a subset of values time_vars.each do |tv_key, tv_val| start_idx = index_of_date_value(first) || 0 last_idx = index_of_date_value(last) || (first.nil? ? -1 : start_idx) answer = (eval(var).each_cons(2).map { |val1, val2| val2 - val1 }.dup.unshift(nil))[start_idx..last_idx] return answer.length == 1 ? answer[0] : answer end end # should DRY out variable creation, probably by passing in a strategy along with the variable name define_method("#{var}_cumsum") do |first=nil, last=nil| # should work only on numeric data # this could be made more efficient by caching the full array and/or calculating only a subset of values time_vars.each do |tv_key, tv_val| start_idx = index_of_date_value(first) || 0 last_idx = index_of_date_value(last) || (first.nil? ? -1 : start_idx) sum = eval(var)[0] answer = (eval(var).each_cons(2).map { |val1, val2| sum += val2 }.dup.unshift(eval(var)[start_idx]))[start_idx..last_idx] return answer.length == 1 ? answer[0] : answer end end end define_var_on(var) instance_variable_set("@#{var}", vals) if vals data_vars[var] = vals unless data_vars.has_key?(var) end
new_time_var(var, vals)
click to toggle source
# File lib/simple_time_series/simple_time_series.rb, line 85 def new_time_var(var, vals) define_getter_and_setter(var) instance_variable_set("@#{var}", vals) if vals time_vars[var] = vals unless time_vars.has_key?(var) define_var_on(var) end
set(data_var, date, value)
click to toggle source
# File lib/simple_time_series/simple_time_series.rb, line 79 def set(data_var, date, value) arr_index = index_of_date_value(date) current(data_var)[arr_index] = value end
sum_by_date(*data_var_names, opts)
click to toggle source
# File lib/simple_time_series/simple_time_series.rb, line 32 def sum_by_date(*data_var_names, opts) arr = [] data_var_names.each do |name| if opts[:start] && opts[:end] arr << find(name, opts[:start], opts[:end], opts) else arr << current(name, opts) end end arr = arr.transpose.map { |arr| arr.reduce(:+) } opts[:prepend_name] ? arr.dup.unshift(opts[:prepend_name]) : arr end
Private Instance Methods
define_data_methods_and_set_values()
click to toggle source
# File lib/simple_time_series/simple_time_series.rb, line 165 def define_data_methods_and_set_values data_vars.each do |var, vals| new_data_var(var, vals) end end
define_getter_and_setter(var)
click to toggle source
# File lib/simple_time_series/simple_time_series.rb, line 171 def define_getter_and_setter(var) ivar = "@#{var}" self.class.class_eval do define_method(var) do |opts={}| instance_variable_get ivar end define_method "#{var}=" do |val| instance_variable_set ivar, val end end end
define_time_methods_and_set_values()
click to toggle source
# File lib/simple_time_series/simple_time_series.rb, line 159 def define_time_methods_and_set_values time_vars.each do |var, vals| new_time_var(var, vals) end end
define_var_on(var)
click to toggle source
# File lib/simple_time_series/simple_time_series.rb, line 137 def define_var_on(var) self.class.class_eval do define_method("#{var}_on") do |first, last=nil, opts={}| time_vars.each do |tv_key, tv_val| # tv_key is something like 'dows' or 'dates' # tv_val is an array of associated values start_idx = index_of_date_value(first) || 0 last_idx = index_of_date_value(last) || (first.nil? ? -1 : start_idx) puts "Called with #{first}, #{last}, #{opts}" if DEBUG puts "start_idx = #{start_idx}; last_idx = #{last_idx}" if DEBUG if start_idx != last_idx return eval(var)[start_idx..last_idx] elsif start_idx return eval(var)[start_idx] else raise "Can't find #{var}_on for #{first}" end end end end end