On 16 Oct 2006, at 22:37, hadley wickham wrote:
puts ttest[‘p.value’] #Prints out p.value
These guys are all vectors in R - do you mean vectors of length one
are converted to the corresponding Ruby primitives? (Also,
confusingly, in R a string is called a character vector of length 1)
Yes you are quite correct. In the basic (default) conversion mode
vectors of length one are converted to Ruby primitives. However, in
the ‘vector’ conversion mode an Array of length one is returned
instead (closer to R semantics). E.g.
irb(main):001:0> require ‘rsruby’
=> true
irb(main):002:0> r = RSRuby.instance
=> #RSRuby:0xb7d11220
irb(main):003:0> r.sum(1,2,3).class
=> Fixnum
irb(main):004:0> RSRuby.set_default_mode(RSRuby::VECTOR_CONVERSION)
=> 1
irb(main):005:0> r.sum(1,2,3).class
=> Array
See the RPy manual for a fuller discussion of the conversion modes.
RSRuby pretty much uses an identical scheme.
- R Vector <=> Ruby Array (homogeneous)
There isn’t really a vector “class” in R, independent of the things
listed above.
Yes - this is a simplification and indeed the documentation is
slightly misleading here. In basic mode R vectors/lists of length > 1
that don’t have a ‘names’ attribute are converted to Arrays.
Whereas if a ‘names’ attribute is included then the vector/list is
converted to a Hash
I think a better mapping would be to Ara’s ArrayFields class. Lists
in R can be accessed by name or by position.
I tentatively agree. My goal for this release was to implement the
RPy conversion routines and test suite as faithfully as possible. In
RPy named lists/vectors are converted to Python Dictionaries which
are (exactly?) equivalent to Ruby Hashes so I kept to that scheme.
As a Ruby programmer first and an R programmer second my general
philosophy was too try and force R concepts into Ruby (hence
converting lists to Hashes) rather than vice-versa. Using something
like ArrayFields gets us closer to R but at the cost of moving away
from ‘canonical’ (i.e. standard library) Ruby. Clearly this is a
balancing act between getting as close to R semantics as possible
without moving too far from ‘normal’ Ruby. For me that balance point
may lie closer to Ruby than for other users.
One final point: The RSRuby conversion routines can be customised by
the user using the ‘proc’ and ‘class’ conversion modes. These
conversion modes are quite powerful and are designed to allow the
user to implement custom routines for any R/Ruby interconversion they
want. Implementing a list <-> ArrayFields converter in the current
system is (moderately) trivial. The code below implements the R ->
Ruby side. One would need to write a suitable to_r method for Array
to do the conversion the other way - left as an exercise for the
reader 
require ‘rubygems’
require_gem ‘arrayfields’
require ‘rsruby’
test_proc = lambda{|x| #This lambda function is called on each
object returned by R
r = RSRuby.instance
names = r.attr(x,‘names’) #It simply tests whether the ‘names’
attribute is present
if names.nil?
return false #returns false if names are not set
else
return true #returns true if they are
end
}
conv_proc = lambda{|x| #If the above function returns true then
this conversion routine is used
r = RSRuby.instance #instead of the inbuilt RSRuby ones.
names = r.attr(x,‘names’) #Retrieve the names
hash = x.to_ruby #Convert the object (x) to Ruby -
results in a Hash
array = [] #But we want an ArrayField
array.fields = names #Set the field names for the ArrayField
names.each do |field| #Set the ArrayField values according to
the values in the Hash
array[field] = hash[field]
end
return array #Return the Array
}
r = RSRuby.instance #Start R
r.t_test.autoconvert(RSRuby::PROC_CONVERSION) #Set the t.test method
to use proc conversion
r.proc_table[test_proc] = conv_proc #Setup the proc table.
conv_proc is run if test_proc returns
#true
ttest = r.t_test([1,2,3]) #Call t.test function -
returns list in R
puts ttest.class #Normally list <=>
Hash, but here it’s an array!
ttest.each_pair do |field,val| #But not just any array
- an array with fields!
puts “#{field} - #{val}”
end
puts ttest[1…3] #That retains order!
Dr Alex G.
Post-Doctoral Researcher
Bioinformatics Center
Institute for Chemical Research
Kyoto University
Gokasho, Uji, Kyoto 611-0011
Japan