module R
Constants
- LIB_DIR
- PLOT
- SESSION
- UTIL
Attributes
Public Class Methods
Source
# File lib/rbbt/util/R/eval.rb, line 122 def self._eval(cmd) ScoutSemaphore.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
Source
# File lib/rbbt/util/R/eval.rb, line 43 def self.clear @@instance = nil if defined? @@instance_process and @@instance_process and Misc.pid_alive? @@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
Source
# 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_alive? pid Process.kill "INT", pid retry else raise $! end rescue Exception Process.kill 9, pid if Misc.pid_alive? pid raise $! ensure Process.waitpid pid if Misc.pid_alive? pid end end end
Source
# File lib/rbbt/util/R/eval.rb, line 139 def self.eval_a(cmd) _eval(cmd).payload end
Source
# File lib/rbbt/util/R/eval.rb, line 147 def self.eval_run(cmd) _eval(cmd) end
Source
# File lib/rbbt/util/R/plot.rb, line 2 def self.field_classes(data) field_samples = [nil] * data.fields.length data.each do |k,vs| vs = [vs] unless Array === vs vs.each_with_index do |v,i| if ! (v.nil? || v == "NA" || v == "") field_samples[i] = v end end break unless field_samples.include?(nil) end field_samples.collect do |v| v = v.first if Array === v case v when FalseClass, TrueClass "'logical'" when Numeric "'numeric'" when String if v.strip =~ /^[-+]?[\d\.]+$/ "'numeric'" else "'character'" end when Time "'Date'" when Symbol "'factor'" else "NA" end end end
Source
# File lib/rbbt/util/R.rb, line 158 def self.hash2Rargs(hash) hash.collect do |k,v| [k.to_s, ruby2R(v)] * "=" end * ", " end
Source
# File lib/rbbt/util/R/eval.rb, line 59 def self.instance @@instance ||= begin clear if File.exist? pid_file and ! Misc.pid_alive?(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
Source
# 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
Source
# File lib/rbbt/util/R/eval.rb, line 21 def self.lockfile @@lockfile ||= socket_file + '.lock' end
Source
# File lib/rbbt/util/R/model.rb, line 7 def self.model_dir=(model_dir) @model_dir = Path === model_dir ? model_dir : Path.setup(model_dir) end
Source
# File lib/rbbt/util/R/eval.rb, line 39 def self.pid_file @@pidfile ||= File.join(workdir, 'pid') end
Source
# 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 = object.dup if Path === object 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
Source
# 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)) 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
Source
# 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' ScoutSemaphore.create_semaphore(@@semfile,1) @@semfile end end
Source
# File lib/rbbt/util/R/eval.rb, line 17 def self.socket_file @@socket_file ||= Rbbt.tmp.R_sockets[R::SESSION].find end
Source
# File lib/rbbt/util/R.rb, line 164 def self.tsv(file, options = {}) options = IndiferentHash.add_defaults :header_hash => '', :sep => / +/, :type => :list, :key_field => 'ID' key_field = IndiferentHash.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
Source
# File lib/rbbt/util/R/eval.rb, line 35 def self.workdir @@workdir ||= socket_file + '.wd' end