Module: R
- Defined in:
- lib/rbbt/util/R.rb,
lib/rbbt/util/R/eval.rb,
lib/rbbt/util/R/plot.rb,
lib/rbbt/util/R/model.rb
Defined Under Namespace
Modules: GIF, PNG, SVG
Classes: Model
Constant Summary
collapse
- LIB_DIR =
Path.setup(File.join(File.expand_path(File.dirname(__FILE__)),'../../../share/Rlib'))
- UTIL =
File.join(LIB_DIR, 'util.R')
- PLOT =
File.join(LIB_DIR, 'plot.R')
- SESSION =
ENV["RServeSession"] || "Session-PID-" + Process.pid.to_s
Class Attribute Summary collapse
Class Method Summary
collapse
Class Attribute Details
.model_dir ⇒ Object
Returns the value of attribute model_dir.
5
6
7
|
# File 'lib/rbbt/util/R/model.rb', line 5
def model_dir
@model_dir
end
|
Class Method Details
._eval(cmd) ⇒ Object
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
# File 'lib/rbbt/util/R/eval.rb', line 122
def self._eval(cmd)
RbbtSemaphore.synchronize(semfile) do
times = 1
begin
instance.eval(cmd)
rescue Rserve::Connection::EvalError
times = times - 1
if times > 0
clear
retry
else
raise $!
end
end
end
end
|
.clear ⇒ Object
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
# File 'lib/rbbt/util/R/eval.rb', line 43
def self.clear
@@instance = nil
if defined? @@instance_process and @@instance_process and Misc.pid_exists? @@instance_process
Log.warn "Clearing Rserver session #{SESSION}, PID #{@@instance_process}"
begin
Process.kill :INT, @@instance_process
rescue Exception
Log.warn "Error killing Rserve (#{@@instance_process}): #{$!.message}"
end
end
FileUtils.rm_rf pid_file if File.exist? pid_file
FileUtils.rm_rf socket_file if File.exist? socket_file
FileUtils.rm_rf lockfile if File.exist? lockfile
FileUtils.rm_rf workdir if File.exist? workdir
end
|
.console(script, options = {}) ⇒ Object
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
123
124
125
126
|
# File 'lib/rbbt/util/R.rb', line 94
def self.console(script, options = {})
TmpFile.with_file do |init_file|
Open.write(init_file) do |f|
f.puts "# Loading basic rbbt environment"
f.puts "library(utils);\n"
f.puts "source('#{R::UTIL}');\n"
f.puts
f.puts script
end
pid = Process.fork do |ppid|
ENV["R_PROFILE"] = init_file
exec("R")
end
begin
Process.waitpid pid
rescue Interrupt
if Misc.pid_exists? pid
Process.kill "INT", pid
retry
else
raise $!
end
rescue Exception
Process.kill 9, pid if Misc.pid_exists? pid
raise $!
ensure
Process.waitpid pid if Misc.pid_exists? pid
end
end
end
|
.eval(cmd) ⇒ Object
143
144
145
|
# File 'lib/rbbt/util/R/eval.rb', line 143
def self.eval(cmd)
eval_a(cmd).first
end
|
.eval_a(cmd) ⇒ Object
139
140
141
|
# File 'lib/rbbt/util/R/eval.rb', line 139
def self.eval_a(cmd)
_eval(cmd).payload
end
|
.eval_run(cmd) ⇒ Object
147
148
149
|
# File 'lib/rbbt/util/R/eval.rb', line 147
def self.eval_run(cmd)
_eval(cmd)
end
|
.hash2Rargs(hash) ⇒ Object
157
158
159
160
161
|
# File 'lib/rbbt/util/R.rb', line 157
def self.hash2Rargs(hash)
hash.collect do |k,v|
[k.to_s, ruby2R(v)] * "="
end * ", "
end
|
.instance ⇒ Object
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
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
|
# File 'lib/rbbt/util/R/eval.rb', line 59
def self.instance
@@instance ||= begin
clear if File.exist? pid_file and ! Misc.pid_exists?(Open.read(pid_file).strip.to_i)
FileUtils.mkdir_p File.dirname(socket_file) unless File.directory?(File.dirname(socket_file))
FileUtils.mkdir_p workdir unless File.directory? workdir
at_exit do
self.clear
end unless defined? @@instance_process
begin
if not File.exist? socket_file
sh_pid = Process.fork do
args = %w(--quiet --no-save --RS-socket)
args << "'#{socket_file}'"
args << "--RS-workdir"
args << "'#{workdir}'"
args << "--RS-pidfile"
args << "'#{pid_file}'"
if ENV["R_HOME"]
bin_path = File.join(ENV["R_HOME"], "bin/Rserve")
else
bin_path = "Rserve"
end
cmd = bin_path + " " + args*" "
$stdout.reopen File.new('/dev/null', 'w')
exec(ENV, cmd)
end
Misc.insist(10, 0.5, false) do
raise "Rserve did not start" unless File.exist? pid_file
end
@@instance_process = Open.read(pid_file).to_i
Log.info "New Rserver session stated with PID (#{sh_pid}) #{@@instance_process}: #{SESSION}"
end
i = Rserve::Connection.new :hostname => socket_file
begin
FileUtils.mkdir workdir unless File.exist? workdir
i.eval "setwd('#{workdir}');"
i.eval "source('#{UTIL}');"
i
rescue Exception
Log.exception $!
raise TryAgain
end
rescue Exception
Log.exception $!
Process.kill :INT, @@instance_process if defined? @@instance_process and @@instance_process
FileUtils.rm socket_file if File.exist? socket_file
retry if TryAgain === $!
raise $!
end
end
end
|
.interactive(script, source = [], options = {}) ⇒ Object
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
# File 'lib/rbbt/util/R.rb', line 59
def self.interactive(script, source = [], options = {})
TmpFile.with_file(script) do |script_file|
TmpFile.with_file do |init_file|
cmd = <<-EOF
# Loading basic rbbt environment"
library(utils, quietly=TRUE);
library(grDevices,quietly=TRUE)
source('#{R::UTIL}');
EOF
require_sources = source.collect{|source|
source = R::LIB_DIR["#{source.to_s}.R"] if R::LIB_DIR["#{source.to_s}.R"].exists?
"source('#{source}')"
} * ";\n" if Array === source and source.any?
cmd << require_sources + "\n\n" if require_sources
cmd += <<-EOF
rbbt.require('readr')
interactive.script.file = '#{script_file}'
interactive.script = read_file(interactive.script.file)
cat(interactive.script)
source(interactive.script.file)
EOF
Open.write init_file, cmd
CMD.cmd("env R_PROFILE='#{init_file}' xterm \"$R_HOME/bin/R\"")
end
end
end
|
.lockfile ⇒ Object
21
22
23
|
# File 'lib/rbbt/util/R/eval.rb', line 21
def self.lockfile
@@lockfile ||= socket_file + '.lock'
end
|
.pid_file ⇒ Object
39
40
41
|
# File 'lib/rbbt/util/R/eval.rb', line 39
def self.pid_file
@@pidfile ||= File.join(workdir, 'pid')
end
|
.ruby2R(object) ⇒ Object
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
# File 'lib/rbbt/util/R.rb', line 128
def self.ruby2R(object)
case object
when Float::INFINITY
"Inf"
when nil
"NULL"
when ":NA"
"NA"
when TSV
"matrix(#{R.ruby2R object.values},dimnames=list(#{R.ruby2R object.keys}, #{R.ruby2R object.fields}))"
when Symbol
"#{ object }"
when String
object[0] == ":" ? object[1..-1] : "'#{ object }'"
when Numeric
object
when TrueClass
"TRUE"
when FalseClass
"FALSE"
when Array
"c(#{object.collect{|e| ruby2R(e) } * ", "})"
when Hash
"list(" << object.collect{|k,v| [k, ruby2R(v)] * "="} * ", " << ")"
else
raise "Type of object not known: #{ object.inspect }"
end
end
|
.run(command, source = nil, options = nil) ⇒ Object
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
# File 'lib/rbbt/util/R.rb', line 13
def self.run(command, source = nil, options = nil)
source, options = nil, source if options.nil? and Hash === source
options = {} if options.nil?
monitor = options.delete :monitor
cmd =<<-EOF
# Loading basic rbbt environment
source('#{UTIL}');
EOF
require_sources = source.collect{|source|
source = R::LIB_DIR["#{source.to_s}.R"] if R::LIB_DIR["#{source.to_s}.R"].exists?
"source('#{source}')"
} * ";\n" if Array === source and source.any?
cmd << require_sources + "\n\n" if require_sources
case
when IO === command
cmd << command.read
when File.exist?(command)
cmd << File.open(command, 'r') do |f| f.read end
else
cmd << command
end
Log.debug{"R Script:\n#{ cmd }"}
if monitor
io = CMD.cmd('R --no-save --quiet', options.merge(:in => cmd, :pipe => true, :log => true, :xvfb => options[:xvfb]))
while line = io.gets
case monitor
when Proc
monitor.call line
else
Log.debug "R: " << line
end
end
io.join if io.respond_to? :join
else
CMD.cmd('R --no-save --slave --quiet', options.merge(:in => cmd, :xvfb => options[:xvfb]))
end
end
|
.semfile ⇒ Object
25
26
27
28
29
30
31
32
33
|
# File 'lib/rbbt/util/R/eval.rb', line 25
def self.semfile
if defined? @@semfile and not @@semfile.nil?
@@semfile
else
@@semfile = File.basename(socket_file) + '.sem'
RbbtSemaphore.create_semaphore(@@semfile,1)
@@semfile
end
end
|
.socket_file ⇒ Object
17
18
19
|
# File 'lib/rbbt/util/R/eval.rb', line 17
def self.socket_file
@@socket_file ||= Rbbt.tmp.R_sockets[R::SESSION].find
end
|
.tsv(file, options = {}) ⇒ Object
163
164
165
166
167
168
|
# File 'lib/rbbt/util/R.rb', line 163
def self.tsv(file, options = {})
options = Misc.add_defaults :header_hash => '', :sep => / +/, :type => :list, :key_field => 'ID'
key_field = Misc.process_options options, :key_field
clean = CMD.cmd('grep -v WARNING', :in => file, :pipe => true)
TSV.open(clean, options).tap{|tsv| tsv.key_field = key_field }
end
|
.workdir ⇒ Object
35
36
37
|
# File 'lib/rbbt/util/R/eval.rb', line 35
def self.workdir
@@workdir ||= socket_file + '.wd'
end
|