rbbt-util 5.14.29 → 5.14.30
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.
- checksums.yaml +4 -4
- data/lib/rbbt/annotations.rb +2 -0
- data/lib/rbbt/association/item.rb +7 -0
- data/lib/rbbt/knowledge_base.rb +17 -7
- data/lib/rbbt/tsv/accessor.rb +10 -4
- data/lib/rbbt/tsv/manipulate.rb +1 -2
- data/lib/rbbt/tsv/util.rb +13 -2
- data/lib/rbbt/util/R/eval.rb +58 -6
- data/lib/rbbt/util/R/model.rb +76 -0
- data/lib/rbbt/util/R.rb +36 -8
- data/lib/rbbt/util/log.rb +1 -1
- data/lib/rbbt/util/misc/inspect.rb +5 -1
- data/lib/rbbt/workflow/definition.rb +6 -0
- data/share/Rlib/util.R +131 -2
- data/test/rbbt/test_resource.rb +0 -1
- data/test/rbbt/util/R/test_eval.rb +28 -1
- data/test/rbbt/util/R/test_model.rb +52 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 961b2aefbda7865869a3c58926e8b14ecde80ecb
|
4
|
+
data.tar.gz: def79057ef14b73031ec710b40b420f4e5356350
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 691ab8d3aec9159ba632b5124a2f00dbadd8bb661e20d9e2c3999d54df939bec38042acdfbcde49474ce476056ca2c458c4019287ad9a4e014e5ee5a814d7732
|
7
|
+
data.tar.gz: 3813a6152181ca3e3d59248adc13e28189d9dac7ed8efaa5df1c30c3e41df4d79091692ce415c9529c24fc94a723e9558821a681d08585d596810c510eb86cb2
|
data/lib/rbbt/annotations.rb
CHANGED
@@ -84,6 +84,7 @@ module AssociationItem
|
|
84
84
|
|
85
85
|
value = self.value
|
86
86
|
value.collect{|v|
|
87
|
+
raise "No info for pair; not registered in index" if v.nil?
|
87
88
|
Hash[*fields.zip(v).flatten]
|
88
89
|
}
|
89
90
|
end
|
@@ -103,6 +104,12 @@ module AssociationItem
|
|
103
104
|
tsv
|
104
105
|
end
|
105
106
|
|
107
|
+
property :filter => :array do |*args,&block|
|
108
|
+
keys = tsv.select(*args,&block).keys
|
109
|
+
keys = self.annotate Annotated.purge(keys)
|
110
|
+
keys
|
111
|
+
end
|
112
|
+
|
106
113
|
def self.incidence(pairs, key_field = nil, &block)
|
107
114
|
matrix = {}
|
108
115
|
targets = []
|
data/lib/rbbt/knowledge_base.rb
CHANGED
@@ -15,7 +15,6 @@ class KnowledgeBase
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
|
19
18
|
def setup(name, matches, reverse = false)
|
20
19
|
AssociationItem.setup matches, self, name, reverse
|
21
20
|
end
|
@@ -64,7 +63,12 @@ class KnowledgeBase
|
|
64
63
|
db_name = [database, name] * "@"
|
65
64
|
file, kb_options = kb.registry[database]
|
66
65
|
options = {}
|
66
|
+
options[:entity_options] = kb_options[:entity_options]
|
67
67
|
options[:undirected] = true if kb_options and kb_options[:undirected]
|
68
|
+
if kb.entity_options
|
69
|
+
options[:entity_options] = kb.entity_options.merge(options[:entity_options] || {})
|
70
|
+
end
|
71
|
+
|
68
72
|
register(db_name, nil, options) do
|
69
73
|
kb.get_database(database)
|
70
74
|
end
|
@@ -158,9 +162,9 @@ class KnowledgeBase
|
|
158
162
|
key = name.to_s + "_" + Misc.digest(Misc.fingerprint([name,options,format,namespace]))
|
159
163
|
@databases[key] ||=
|
160
164
|
begin
|
161
|
-
|
165
|
+
file, registered_options = registry[name]
|
166
|
+
database = Persist.memory("Database:" << [key, dir] * "@") do
|
162
167
|
persist_file = dir.databases[key]
|
163
|
-
file, registered_options = registry[name]
|
164
168
|
|
165
169
|
options = Misc.add_defaults options, :persist_file => persist_file, :namespace => namespace, :format => format
|
166
170
|
options = Misc.add_defaults options, registered_options if registered_options
|
@@ -180,6 +184,10 @@ class KnowledgeBase
|
|
180
184
|
|
181
185
|
database
|
182
186
|
end
|
187
|
+
|
188
|
+
database.entity_options ||= {}
|
189
|
+
database.entity_options.merge! registered_options[:entity_options] if registered_options.include? :entity_options
|
190
|
+
database
|
183
191
|
end
|
184
192
|
end
|
185
193
|
|
@@ -247,8 +255,10 @@ class KnowledgeBase
|
|
247
255
|
options = entity_options[Entity.formats[type]] || {}
|
248
256
|
options[:format] = @format[type] if @format.include? :type
|
249
257
|
options = {:organism => namespace}.merge(options)
|
250
|
-
if database_name and
|
251
|
-
|
258
|
+
if database_name and
|
259
|
+
(database = get_database(database_name)).entity_options and
|
260
|
+
(database = get_database(database_name)).entity_options[type]
|
261
|
+
options = options.merge database.entity_options[type]
|
252
262
|
end
|
253
263
|
options
|
254
264
|
end
|
@@ -299,7 +309,7 @@ class KnowledgeBase
|
|
299
309
|
|
300
310
|
def identify_target(name, entity)
|
301
311
|
database = get_database(name, :persist => true)
|
302
|
-
return entity if Symbol === entity or (String === entity and database.values.collect{|v| v.first}.compact.flatten.include?(entity))
|
312
|
+
return entity if Symbol === entity #or (String === entity) # and database.values.collect{|v| v.first}.compact.flatten.include?(entity))
|
303
313
|
target = target(name)
|
304
314
|
|
305
315
|
@identifiers[name] ||= {}
|
@@ -347,7 +357,7 @@ class KnowledgeBase
|
|
347
357
|
|
348
358
|
def parents(name, entity)
|
349
359
|
repo = get_index name
|
350
|
-
setup(name, repo.reverse.match(entity))
|
360
|
+
setup(name, repo.reverse.match(entity), true)
|
351
361
|
end
|
352
362
|
|
353
363
|
def neighbours(name, entity)
|
data/lib/rbbt/tsv/accessor.rb
CHANGED
@@ -39,8 +39,11 @@ module TSV
|
|
39
39
|
return entity unless defined? Entity
|
40
40
|
entity = entity if options.delete :dup_array
|
41
41
|
if (template = entity_templates[field]) and template.respond_to?(:annotate)
|
42
|
-
|
43
|
-
|
42
|
+
if String === entity or Array === entity
|
43
|
+
entity = entity.dup if entity.frozen?
|
44
|
+
template.annotate entity
|
45
|
+
entity.extend AnnotatedArray if Array === entity
|
46
|
+
end
|
44
47
|
entity
|
45
48
|
else
|
46
49
|
if entity_templates.include? field
|
@@ -49,8 +52,11 @@ module TSV
|
|
49
52
|
template = Misc.prepare_entity("TEMPLATE", field, options)
|
50
53
|
if template.respond_to?(:annotate)
|
51
54
|
entity_templates[field] = template
|
52
|
-
|
53
|
-
|
55
|
+
if String === entity or Array === entity
|
56
|
+
entity = entity.dup if entity.frozen?
|
57
|
+
template.annotate entity
|
58
|
+
entity.extend AnnotatedArray if Array === entity
|
59
|
+
end
|
54
60
|
entity
|
55
61
|
else
|
56
62
|
entity_templates[field] = nil
|
data/lib/rbbt/tsv/manipulate.rb
CHANGED
@@ -558,7 +558,6 @@ module TSV
|
|
558
558
|
field_pos = identify_field field
|
559
559
|
|
560
560
|
through do |key, values|
|
561
|
-
next if values.nil?
|
562
561
|
|
563
562
|
case
|
564
563
|
when type == :single
|
@@ -566,7 +565,7 @@ module TSV
|
|
566
565
|
when type == :flat
|
567
566
|
field_values = values
|
568
567
|
else
|
569
|
-
next if values
|
568
|
+
next if values.nil?
|
570
569
|
field_values = values[field_pos]
|
571
570
|
end
|
572
571
|
|
data/lib/rbbt/tsv/util.rb
CHANGED
@@ -177,6 +177,11 @@ module TSV
|
|
177
177
|
TSV.identify_field(key_field, fields, field)
|
178
178
|
end
|
179
179
|
|
180
|
+
def rename_field(field, new)
|
181
|
+
self.fields = self.fields.collect{|f| f == field ? new : f }
|
182
|
+
self
|
183
|
+
end
|
184
|
+
|
180
185
|
def to_list
|
181
186
|
new = {}
|
182
187
|
case type
|
@@ -220,8 +225,14 @@ module TSV
|
|
220
225
|
new[k] = [[v]]
|
221
226
|
end
|
222
227
|
when :list
|
223
|
-
|
224
|
-
|
228
|
+
if block_given?
|
229
|
+
through do |k,v|
|
230
|
+
new[k] = v.collect{|e| yield e}
|
231
|
+
end
|
232
|
+
else
|
233
|
+
through do |k,v|
|
234
|
+
new[k] = v.collect{|e| [e]}
|
235
|
+
end
|
225
236
|
end
|
226
237
|
end
|
227
238
|
self.annotate(new)
|
data/lib/rbbt/util/R/eval.rb
CHANGED
@@ -1,17 +1,69 @@
|
|
1
|
+
require 'rbbt/util/R'
|
2
|
+
require 'rserve'
|
3
|
+
|
4
|
+
# Hack to make it work with local sockets
|
5
|
+
module Rserve
|
6
|
+
module TCPSocket
|
7
|
+
def self.new(hostname, port_number)
|
8
|
+
raise "Socket at #{hostname} not found" unless File.exists? hostname
|
9
|
+
@s = Socket.unix hostname
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
1
14
|
module R
|
15
|
+
PID = Process.pid
|
2
16
|
def self.instance
|
3
17
|
@@instance ||= begin
|
4
|
-
|
5
|
-
|
6
|
-
|
18
|
+
@@socket_file = Rbbt.tmp.R_sockets[R::PID].find
|
19
|
+
|
20
|
+
FileUtils.mkdir_p File.dirname(@@socket_file) unless File.directory?(File.dirname(@@socket_file))
|
21
|
+
|
22
|
+
begin
|
23
|
+
|
24
|
+
if not File.exists? @@socket_file
|
25
|
+
|
26
|
+
@@instance_process = Process.fork do
|
27
|
+
args = %w(CMD Rserve --vanilla --quiet --RS-socket)
|
28
|
+
args << "'#{@@socket_file}'"
|
29
|
+
|
30
|
+
bin_path = "R"
|
31
|
+
cmd = bin_path + " " + args*" "
|
32
|
+
exec(ENV, cmd)
|
33
|
+
end
|
34
|
+
sleep 1
|
35
|
+
end
|
36
|
+
|
37
|
+
begin
|
38
|
+
i = Rserve::Connection.new :hostname => @@socket_file
|
39
|
+
i.eval "source('#{UTIL}');"
|
40
|
+
i
|
41
|
+
rescue Exception
|
42
|
+
raise TryAgain
|
43
|
+
end
|
44
|
+
rescue Exception
|
45
|
+
Process.kill :INT, @@instance_process if defined? @@instance_process and @@instance_process
|
46
|
+
FileUtils.rm @@socket_file if File.exists? @@socket_file
|
47
|
+
retry if TryAgain === $!
|
48
|
+
raise $!
|
49
|
+
end
|
7
50
|
end
|
8
51
|
end
|
9
52
|
|
10
|
-
def self.
|
11
|
-
instance.eval(cmd)
|
53
|
+
def self._eval(cmd)
|
54
|
+
instance.eval(cmd)
|
12
55
|
end
|
13
56
|
|
14
57
|
def self.eval_a(cmd)
|
15
|
-
|
58
|
+
_eval(cmd).payload
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.eval(cmd)
|
62
|
+
eval_a(cmd).first
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.eval_run(cmd)
|
66
|
+
_eval(cmd)
|
16
67
|
end
|
68
|
+
|
17
69
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'rbbt/util/R'
|
2
|
+
|
3
|
+
module R
|
4
|
+
|
5
|
+
class << self
|
6
|
+
attr_accessor :model_dir
|
7
|
+
|
8
|
+
def self.model_dir=(model_dir)
|
9
|
+
@model_dir = Path === model_dir ? model_dir : Path.setup(model_dir)
|
10
|
+
end
|
11
|
+
def self.model_dir
|
12
|
+
@model_dir ||= Rbbt.var.R.models
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
self.model_dir = Rbbt.var.R.models
|
18
|
+
class Model
|
19
|
+
|
20
|
+
attr_accessor :name, :formula
|
21
|
+
def initialize(name, formula)
|
22
|
+
@name = name
|
23
|
+
@formula = formula
|
24
|
+
end
|
25
|
+
|
26
|
+
def model_file
|
27
|
+
@model_file ||= R.model_dir[Misc.name2basename([name, Misc.name2basename(formula)] * ": ")].find
|
28
|
+
end
|
29
|
+
|
30
|
+
def update(tsv, field = "Prediction")
|
31
|
+
tsv.R <<-EOF, :R_method => :eval
|
32
|
+
model = rbbt.model.load('#{model_file}');
|
33
|
+
model = update(model, data);
|
34
|
+
save(model, file='#{model_file}');
|
35
|
+
EOF
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.groom(tsv, formula)
|
39
|
+
tsv = tsv.to_list if tsv.type == :single
|
40
|
+
|
41
|
+
if formula.include? tsv.key_field and not tsv.fields.include? tsv.key_field
|
42
|
+
tsv = tsv.add_field tsv.key_field do |k,v|
|
43
|
+
k
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
tsv
|
48
|
+
end
|
49
|
+
|
50
|
+
def predict(tsv, field = "Prediction")
|
51
|
+
tsv = Model.groom tsv, formula
|
52
|
+
tsv.R <<-EOF, :R_method => :eval, :key => tsv.key_field
|
53
|
+
model = rbbt.model.load('#{model_file}');
|
54
|
+
data$#{field} = predict(model, data);
|
55
|
+
EOF
|
56
|
+
end
|
57
|
+
|
58
|
+
def exists?
|
59
|
+
File.exists? model_file
|
60
|
+
end
|
61
|
+
|
62
|
+
def fit(tsv, method='lm', args = {})
|
63
|
+
args_str = ""
|
64
|
+
args_str = args.collect{|name,value| [name,R.ruby2R(value)] * "=" } * ", "
|
65
|
+
args_str = ", " << args_str unless args_str.empty?
|
66
|
+
|
67
|
+
tsv = Model.groom(tsv, formula)
|
68
|
+
|
69
|
+
FileUtils.mkdir_p File.dirname(model_file) unless File.exists?(File.dirname(model_file))
|
70
|
+
tsv.R <<-EOF, :R_method => :shell
|
71
|
+
model = rbbt.model.fit(data, #{formula}, method=#{method}#{args_str})
|
72
|
+
save(model, file='#{model_file}')
|
73
|
+
EOF
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/rbbt/util/R.rb
CHANGED
@@ -26,7 +26,7 @@ source('#{UTIL}');
|
|
26
26
|
Log.debug{"R Script:\n#{ cmd }"}
|
27
27
|
|
28
28
|
if options.delete :monitor
|
29
|
-
io = CMD.cmd('R --vanilla', options.merge(:in => cmd, :pipe => true, :log => true))
|
29
|
+
io = CMD.cmd('R --vanilla --quiet', options.merge(:in => cmd, :pipe => true, :log => true))
|
30
30
|
while line = io.gets
|
31
31
|
puts line
|
32
32
|
end
|
@@ -40,7 +40,7 @@ source('#{UTIL}');
|
|
40
40
|
TmpFile.with_file do |init_file|
|
41
41
|
Open.write(init_file) do |f|
|
42
42
|
f.puts "# Loading basic rbbt environment"
|
43
|
-
f.puts "library(utils);\n"
|
43
|
+
f.puts "library(utils, quietly=TRUE);\n"
|
44
44
|
f.puts "source('#{R::UTIL}');\n"
|
45
45
|
f.puts
|
46
46
|
f.puts script
|
@@ -117,13 +117,37 @@ end
|
|
117
117
|
|
118
118
|
module TSV
|
119
119
|
|
120
|
-
def R(script, open_options = {})
|
121
|
-
|
120
|
+
def R(script, source = nil, open_options = {})
|
121
|
+
open_options, source = source, nil if Hash === source
|
122
|
+
|
123
|
+
source = [source] if String === source
|
124
|
+
|
125
|
+
require_sources = source.collect{|source|
|
126
|
+
"source('#{source}');"
|
127
|
+
} * ";\n" if Array === source and source.any?
|
128
|
+
|
129
|
+
script = require_sources + "\n\n" + script if require_sources
|
130
|
+
|
131
|
+
r_options = Misc.pull_keys open_options, :R
|
132
|
+
r_options[:debug] = true if r_options[:method] == :debug
|
133
|
+
if r_options.delete :debug
|
134
|
+
r_options[:monitor] = true
|
135
|
+
r_options[:method] = :shell
|
136
|
+
erase = false
|
137
|
+
else
|
138
|
+
erase = true
|
139
|
+
end
|
140
|
+
|
141
|
+
tsv_R_option_str = r_options.delete :open
|
142
|
+
tsv_R_option_str = ", " + tsv_R_option_str if String === tsv_R_option_str and not tsv_R_option_str.empty?
|
143
|
+
|
144
|
+
raw = open_options.delete :raw
|
145
|
+
TmpFile.with_file nil, erase do |f|
|
122
146
|
Open.write(f, self.to_s)
|
123
147
|
|
124
148
|
script = <<-EOF
|
125
149
|
## Loading tsv into data
|
126
|
-
data = rbbt.tsv('#{f}');
|
150
|
+
data = rbbt.tsv('#{f}'#{tsv_R_option_str});
|
127
151
|
|
128
152
|
#{script.strip}
|
129
153
|
|
@@ -131,12 +155,16 @@ data = rbbt.tsv('#{f}');
|
|
131
155
|
if (! is.null(data)){ rbbt.tsv.write('#{f}', data); }
|
132
156
|
EOF
|
133
157
|
|
134
|
-
r_options = Misc.pull_keys open_options, :R
|
135
|
-
io = R.run script, r_options
|
136
158
|
|
159
|
+
case r_options.delete :method
|
160
|
+
when :eval
|
161
|
+
R.eval_run script
|
162
|
+
else
|
163
|
+
R.run script, r_options
|
164
|
+
end
|
137
165
|
|
138
166
|
open_options = Misc.add_defaults open_options, :type => :list
|
139
|
-
if
|
167
|
+
if raw
|
140
168
|
Open.read(f)
|
141
169
|
else
|
142
170
|
tsv = TSV.open(f, open_options) unless open_options[:ignore_output]
|
data/lib/rbbt/util/log.rb
CHANGED
@@ -2,6 +2,10 @@ module Misc
|
|
2
2
|
ARRAY_MAX_LENGTH = 1000
|
3
3
|
STRING_MAX_LENGTH = ARRAY_MAX_LENGTH * 10
|
4
4
|
|
5
|
+
def self.name2basename(file)
|
6
|
+
sanitize_filename(file.gsub("/",'>').gsub("~", '-'))
|
7
|
+
end
|
8
|
+
|
5
9
|
def self.sanitize_filename(filename, length = 254)
|
6
10
|
if filename.length > length
|
7
11
|
if filename =~ /(\..{2,9})$/
|
@@ -157,7 +161,7 @@ module Misc
|
|
157
161
|
|
158
162
|
end
|
159
163
|
|
160
|
-
str << "_" << hash2md5(v.info) if defined? Annotated and Annotated === v
|
164
|
+
str << "_" << hash2md5(v.info) if defined? Annotated and Annotated === v and not AssociationItem === v
|
161
165
|
end
|
162
166
|
hash.unnamed = unnamed if hash.respond_to? :unnamed
|
163
167
|
|
@@ -97,13 +97,19 @@ module Workflow
|
|
97
97
|
|
98
98
|
def export_exec(*names)
|
99
99
|
exec_exports.concat names
|
100
|
+
exec_exports.uniq!
|
101
|
+
exec_exports
|
100
102
|
end
|
101
103
|
|
102
104
|
def export_asynchronous(*names)
|
103
105
|
asynchronous_exports.concat names
|
106
|
+
asynchronous_exports.uniq!
|
107
|
+
asynchronous_exports
|
104
108
|
end
|
105
109
|
|
106
110
|
def export_synchronous(*names)
|
107
111
|
synchronous_exports.concat names
|
112
|
+
synchronous_exports.uniq!
|
113
|
+
synchronous_exports
|
108
114
|
end
|
109
115
|
end
|
data/share/Rlib/util.R
CHANGED
@@ -207,9 +207,12 @@ rbbt.init <- function(data, new){
|
|
207
207
|
}
|
208
208
|
}
|
209
209
|
|
210
|
-
rbbt.this.script =
|
210
|
+
rbbt.this.script = NULL;
|
211
211
|
|
212
212
|
rbbt.reload <- function (){
|
213
|
+
if (is.null(rbbt.this.script)){
|
214
|
+
rbbt.this.script = system("rbbt_Rutil.rb", intern =T)
|
215
|
+
}
|
213
216
|
source(rbbt.this.script)
|
214
217
|
}
|
215
218
|
|
@@ -302,7 +305,8 @@ rbbt.plot.matrix <- function(x, ...){
|
|
302
305
|
}
|
303
306
|
|
304
307
|
rbbt.log <- function(m){
|
305
|
-
|
308
|
+
head = "R-Rbbt"
|
309
|
+
cat(paste(head, "> ", m,"\n",sep=""), file = stderr())
|
306
310
|
}
|
307
311
|
|
308
312
|
rbbt.ddd <- function(o){
|
@@ -310,3 +314,128 @@ rbbt.ddd <- function(o){
|
|
310
314
|
cat("\n", file = stderr())
|
311
315
|
}
|
312
316
|
|
317
|
+
|
318
|
+
|
319
|
+
# {{{ MODELS
|
320
|
+
|
321
|
+
|
322
|
+
rbbt.model.fit <- function(data, formula, method=lm, ...){
|
323
|
+
method(formula, data = data, ...);
|
324
|
+
}
|
325
|
+
|
326
|
+
rbbt.model.groom <- function(data, variables = NULL, classes = NULL, formula = NULL){
|
327
|
+
names = names(data)
|
328
|
+
if (is.null(variables)){
|
329
|
+
if (is.null(formula)){
|
330
|
+
variables = names
|
331
|
+
}
|
332
|
+
variables = names[names %in% all.vars(formula)]
|
333
|
+
}
|
334
|
+
|
335
|
+
data.groomed = data[,variables]
|
336
|
+
|
337
|
+
if (! is.null(classes)){
|
338
|
+
if (is.character(classes)){ classes = rep(classes,dim(data.groomed)[2]) }
|
339
|
+
i = 1
|
340
|
+
for (class in classes){
|
341
|
+
v = data.groomed[, i]
|
342
|
+
v = switch(class, numeric =as.numeric(v), character = as.character(v), factor = as.factor(v), boolean = as.logical(v), logical = as.logical(v))
|
343
|
+
data.groomed[,i] = v
|
344
|
+
i = i+1
|
345
|
+
}
|
346
|
+
}
|
347
|
+
|
348
|
+
data.groomed
|
349
|
+
}
|
350
|
+
|
351
|
+
rbbt.model.predict <- function(model, data, ...){
|
352
|
+
predictions = predict(model, newdata = data, ...);
|
353
|
+
predictions
|
354
|
+
}
|
355
|
+
|
356
|
+
rbbt.loaded.models = list();
|
357
|
+
rbbt.model.load <- function(file, force = F){
|
358
|
+
if (is.null(rbbt.loaded.models[[file]])){
|
359
|
+
load(file)
|
360
|
+
rbbt.loaded.models[[file]] = model
|
361
|
+
}
|
362
|
+
rbbt.loaded.models[[file]]
|
363
|
+
}
|
364
|
+
|
365
|
+
rbbt.pull.keys <- function(items, key){
|
366
|
+
pulled = list()
|
367
|
+
rest = list()
|
368
|
+
|
369
|
+
names = names(items)
|
370
|
+
|
371
|
+
prefix = paste("^",key,'.',sep='')
|
372
|
+
matches = grep(prefix, names)
|
373
|
+
|
374
|
+
for (i in seq(1,length(names))){
|
375
|
+
if (i %in% matches){
|
376
|
+
name = names[i]
|
377
|
+
name = sub(prefix, "", name)
|
378
|
+
pulled[[name]] = items[[i]]
|
379
|
+
}else{
|
380
|
+
name = names[i]
|
381
|
+
rest[[name]] = items[[i]]
|
382
|
+
}
|
383
|
+
}
|
384
|
+
|
385
|
+
list(pulled=pulled, rest=rest)
|
386
|
+
}
|
387
|
+
|
388
|
+
rbbt.model.add_fit <- function(data, formula, method, classes=NULL, ...){
|
389
|
+
data.groomed = rbbt.model.groom(data, formula=formula, classes = classes);
|
390
|
+
|
391
|
+
args = list(...)
|
392
|
+
args.pull = rbbt.pull.keys(args, 'predict')
|
393
|
+
predict.args = args.pull$pulled
|
394
|
+
|
395
|
+
args.pull = rbbt.pull.keys(args.pull$rest, 'fit')
|
396
|
+
|
397
|
+
fit.args = args.pull$pulled
|
398
|
+
args.rest = args.pull$rest
|
399
|
+
|
400
|
+
fit.args =c(fit.args, args.rest)
|
401
|
+
predict.args =c(predict.args, args.rest)
|
402
|
+
|
403
|
+
fit.args[["data"]] = data.groomed
|
404
|
+
fit.args[["formula"]] = formula
|
405
|
+
fit.args[["method"]] = method
|
406
|
+
|
407
|
+
model = do.call(rbbt.model.fit, fit.args);
|
408
|
+
|
409
|
+
response = rbbt.model.formula.reponse(formula)
|
410
|
+
data.groomed[[response]] = NULL
|
411
|
+
|
412
|
+
predict.args[["model"]] = model
|
413
|
+
predict.args[["data"]] = data.groomed
|
414
|
+
|
415
|
+
predictions = do.call(rbbt.model.predict,predict.args)
|
416
|
+
|
417
|
+
data$Prediction = predictions;
|
418
|
+
data
|
419
|
+
}
|
420
|
+
|
421
|
+
rbbt.model.formula.reponse <- function(formula){
|
422
|
+
tt <- terms(formula)
|
423
|
+
vars <- as.character(attr(tt, "variables"))[-1] ## [1] is the list call
|
424
|
+
response.index <- attr(tt, "response") # index of response var
|
425
|
+
as.character(vars[response.index])
|
426
|
+
}
|
427
|
+
|
428
|
+
rbbt.model.inpute <- function(data, formula, ...){
|
429
|
+
data = rbbt.model.add_fit(data, formula=formula, ...)
|
430
|
+
|
431
|
+
response = rbbt.model.formula.reponse(formula)
|
432
|
+
|
433
|
+
rows = rownames(data)
|
434
|
+
missing = rows[is.na(data[,c(response)])]
|
435
|
+
|
436
|
+
predictions = data[missing, "Prediction"]
|
437
|
+
|
438
|
+
data[missing,c(response)] = predictions
|
439
|
+
# data$Prediction = NULL
|
440
|
+
data
|
441
|
+
}
|
data/test/rbbt/test_resource.rb
CHANGED
@@ -3,7 +3,7 @@ require 'rbbt/util/R/eval'
|
|
3
3
|
|
4
4
|
class TestREval < Test::Unit::TestCase
|
5
5
|
def test_get
|
6
|
-
Misc.benchmark(
|
6
|
+
Misc.benchmark(1000) do
|
7
7
|
a = R.eval <<-EOF
|
8
8
|
p = 12
|
9
9
|
a = p * 2
|
@@ -12,5 +12,32 @@ class TestREval < Test::Unit::TestCase
|
|
12
12
|
assert_equal 12 * 2, a
|
13
13
|
end
|
14
14
|
end
|
15
|
+
|
16
|
+
def test_TSV_fork
|
17
|
+
tsv = TSV.setup({"1" => "1"},:type => :single)
|
18
|
+
a = tsv.R <<-EOF, :R_method => :eval
|
19
|
+
p = 12
|
20
|
+
a = p * 2
|
21
|
+
c(a)
|
22
|
+
EOF
|
23
|
+
|
24
|
+
pid = Process.fork do
|
25
|
+
a = tsv.R <<-EOF, :R_method => :eval
|
26
|
+
p = 12
|
27
|
+
a = p * 2
|
28
|
+
c(a)
|
29
|
+
EOF
|
30
|
+
end
|
31
|
+
s = Process.waitpid2 pid
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_TSV
|
35
|
+
tsv = TSV.setup({"1" => "1"},:type => :single)
|
36
|
+
a = tsv.R <<-EOF, :R_method => :eval
|
37
|
+
p = 12
|
38
|
+
a = p * 2
|
39
|
+
c(a)
|
40
|
+
EOF
|
41
|
+
end
|
15
42
|
end
|
16
43
|
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '../../..', 'test_helper.rb')
|
2
|
+
require 'rbbt/util/R/model'
|
3
|
+
|
4
|
+
class TestRModel < Test::Unit::TestCase
|
5
|
+
def model
|
6
|
+
end
|
7
|
+
|
8
|
+
def _test_fit
|
9
|
+
data = TSV.setup({}, :key_field => "Dose", :fields => ["Response"], :type => :single)
|
10
|
+
10.times do
|
11
|
+
x = rand(10)
|
12
|
+
y = 10 + 3 * x + rand * 4
|
13
|
+
data[x] = y
|
14
|
+
end
|
15
|
+
|
16
|
+
model = R::Model.new "Test fit 2", "Response ~ Dose"
|
17
|
+
|
18
|
+
model.fit(data, method='drm', :fct => "LL.3()") unless model.exists?
|
19
|
+
|
20
|
+
x = 5
|
21
|
+
y = 10 + 3 * x
|
22
|
+
input = TSV.setup({"new 1" => [x]}, :key_field => "Code", :fields => ["Dose"], :type => :single)
|
23
|
+
puts model.predict(input).to_s
|
24
|
+
pred = model.predict(input)["new 1"]["Prediction"].to_f
|
25
|
+
assert pred > y and pred < y + 4
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_add_fit
|
29
|
+
tsv = TSV.open datafile_test('dose_response'), :type => :list
|
30
|
+
tsv = tsv.slice(["Dose", "Response"])
|
31
|
+
|
32
|
+
result = tsv.R <<-EOF, :R_debug => true
|
33
|
+
library(drc, quietly=T)
|
34
|
+
library(txtplot)
|
35
|
+
data = rbbt.model.add_fit(data, Response ~ Dose, method=drm, classes='numeric', fct=LL.4(),na.action=na.omit)
|
36
|
+
txtplot(data$Dose, data$Response)
|
37
|
+
txtplot(data$Dose, data$Prediction)
|
38
|
+
EOF
|
39
|
+
ppp result
|
40
|
+
end
|
41
|
+
|
42
|
+
def _test_add_inpute
|
43
|
+
tsv = TSV.open datafile_test('dose_response'), :type => :list
|
44
|
+
|
45
|
+
result = tsv.R <<-EOF, :R_debug => true
|
46
|
+
library(drc, quietly=T)
|
47
|
+
data = rbbt.model.inpute(data, CI ~ Dose, method=drm, classes='numeric', fct=LL.4(), na.action=na.exclude)
|
48
|
+
EOF
|
49
|
+
|
50
|
+
assert_equal result.size, result.column("CI").values.flatten.reject{|p| p.nil? or p.empty? or p == "NA"}.length
|
51
|
+
end
|
52
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbbt-util
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.14.
|
4
|
+
version: 5.14.30
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Miguel Vazquez
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-09-
|
11
|
+
date: 2014-09-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -187,6 +187,7 @@ files:
|
|
187
187
|
- lib/rbbt/tsv/util.rb
|
188
188
|
- lib/rbbt/util/R.rb
|
189
189
|
- lib/rbbt/util/R/eval.rb
|
190
|
+
- lib/rbbt/util/R/model.rb
|
190
191
|
- lib/rbbt/util/chain_methods.rb
|
191
192
|
- lib/rbbt/util/cmd.rb
|
192
193
|
- lib/rbbt/util/color.rb
|
@@ -340,6 +341,7 @@ files:
|
|
340
341
|
- test/rbbt/tsv/test_stream.rb
|
341
342
|
- test/rbbt/tsv/test_util.rb
|
342
343
|
- test/rbbt/util/R/test_eval.rb
|
344
|
+
- test/rbbt/util/R/test_model.rb
|
343
345
|
- test/rbbt/util/concurrency/processes/test_socket.rb
|
344
346
|
- test/rbbt/util/concurrency/test_processes.rb
|
345
347
|
- test/rbbt/util/concurrency/test_threads.rb
|
@@ -419,6 +421,7 @@ test_files:
|
|
419
421
|
- test/rbbt/util/test_semaphore.rb
|
420
422
|
- test/rbbt/util/test_misc.rb
|
421
423
|
- test/rbbt/util/test_tmpfile.rb
|
424
|
+
- test/rbbt/util/R/test_model.rb
|
422
425
|
- test/rbbt/util/R/test_eval.rb
|
423
426
|
- test/rbbt/test_packed_index.rb
|
424
427
|
- test/rbbt/test_association.rb
|