Class: R::Model

Inherits:
Object
  • Object
show all
Defined in:
lib/rbbt/util/R/model.rb

Constant Summary collapse

R_METHOD =
:eval

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, formula, data = nil, options = {}) ⇒ Model

Returns a new instance of Model.



21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/rbbt/util/R/model.rb', line 21

def initialize(name, formula, data = nil, options = {})
  @name = name
  @formula = formula
  @options = options || {}
  @model_file = options[:model_file] if options[:model_file]
  @model_file ||= Misc.sanitize_filename(File.join(options[:model_dir], name)) if options[:model_dir]

  if data and not model_file.exists?
    method = Misc.process_options options, :fit
    fit(data, method || "lm", options)
  end
end

Instance Attribute Details

#formulaObject

Returns the value of attribute formula.



20
21
22
# File 'lib/rbbt/util/R/model.rb', line 20

def formula
  @formula
end

#model_fileObject

Returns the value of attribute model_file.



20
21
22
# File 'lib/rbbt/util/R/model.rb', line 20

def model_file
  @model_file
end

#nameObject

Returns the value of attribute name.



20
21
22
# File 'lib/rbbt/util/R/model.rb', line 20

def name
  @name
end

Class Method Details

.groom(tsv, formula) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
# File 'lib/rbbt/util/R/model.rb', line 68

def self.groom(tsv, formula)
  tsv = tsv.to_list if tsv.type == :single

  if formula.include? tsv.key_field and not tsv.fields.include? tsv.key_field
    tsv = tsv.add_field tsv.key_field do |k,v|
      k
    end
  end

  tsv
end

.load(model_file) ⇒ Object



34
35
36
37
38
39
# File 'lib/rbbt/util/R/model.rb', line 34

def self.load(model_file)
  model = Model.new nil, nil, nil, :model_file => model_file
  formula = Open.read(model_file + '.formula')
  model.formula = formula
  model
end

Instance Method Details

#colClasses(tsv) ⇒ Object



42
43
44
45
46
47
# File 'lib/rbbt/util/R/model.rb', line 42

def colClasses(tsv)
  return nil unless TSV === tsv
  "c('character', " << 
  (tsv.fields.collect{|f| R.ruby2R(@options[f] ? @options[f].to_s : ":NA") } * ", ") <<
  ")"
end

#exists?Boolean

Returns:

  • (Boolean)


124
125
126
# File 'lib/rbbt/util/R/model.rb', line 124

def exists?
  File.exist? model_file
end

#fit(tsv, method = 'lm', args = {}) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/rbbt/util/R/model.rb', line 128

def fit(tsv, method='lm', args = {})
  args_str = ""
  args_str = args.collect{|name,value| [name,R.ruby2R(value)] * "=" } * ", "
  args_str = ", " << args_str unless args_str.empty?

  tsv = Model.groom(tsv, formula)

  FileUtils.mkdir_p File.dirname(model_file) unless File.exist?(File.dirname(model_file))
  roptions = r_options(tsv)
  tsv.R <<-EOF, roptions
model = rbbt.model.fit(data, #{formula}, method=#{method}#{args_str})
save(model, file='#{model_file}')
data = NULL
  EOF
  Open.write(model_file + '.formula', formula)
end

#predict(tsv, field = "Prediction") ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/rbbt/util/R/model.rb', line 93

def predict(tsv, field = "Prediction")
  case tsv
  when TSV
    tsv = Model.groom tsv, formula 
    tsv.R <<-EOF, r_options(tsv)
model = rbbt.model.load('#{model_file}');
data.groomed = rbbt.model.groom(data,formula=#{formula})
data$#{field} = predict(model, data.groomed);
    EOF
  when Hash
    res = R.eval_a <<-EOF
model = rbbt.model.load('#{model_file}');
predict(model, data.frame(#{R.ruby2R tsv}));
    EOF
    Array === tsv.values.first ? res : res.first
  when Numeric, Array, String
    field = formula.split("~").last.strip
    field.gsub!(/log\((.*)\)/,'\1')

    script = <<-EOF
model = rbbt.model.load('#{model_file}');
predict(model, data.frame(#{field} = #{R.ruby2R tsv}));
    EOF

    res = R.eval_a script
    Array === tsv ? res : res.first
  else
    raise "Unknown object for predict: #{Misc.fingerprint tsv}"
  end
end

#predict_interval(value, interval = 'confidence') ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/rbbt/util/R/model.rb', line 80

def predict_interval(value, interval='confidence')
  field = formula.split("~").last.strip
  field.gsub!(/log\((.*)\)/,'\1')

  script = <<-EOF
model = rbbt.model.load('#{model_file}');
predict(model, data.frame(#{field} = #{R.ruby2R value}), interval=#{R.ruby2R interval}, level=0.90);
  EOF

  res = R.eval_a script
  Hash[*%w(fit lower upper).zip(res).flatten]
end

#r_options(tsv) ⇒ Object



49
50
51
52
53
# File 'lib/rbbt/util/R/model.rb', line 49

def r_options(tsv)
  {:R_open => "colClasses=#{colClasses(tsv)}", 
    :R_method => (@options[:R_method] || R_METHOD), 
      :source => @options[:source]}
end

#update(tsv, field = "Prediction") ⇒ Object



59
60
61
62
63
64
65
66
# File 'lib/rbbt/util/R/model.rb', line 59

def update(tsv, field = "Prediction")
  tsv.R <<-EOF, r_options(tsv)
model = rbbt.model.load('#{model_file}');
model = update(model, data);
save(model, file='#{model_file}');
data = NULL
  EOF
end