rsruby 0.4.0 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest.txt ADDED
@@ -0,0 +1,37 @@
1
+ History.txt
2
+ License.txt
3
+ Manifest.txt
4
+ README.txt
5
+ examples/arrayfields.rb
6
+ examples/bioc.rb
7
+ examples/dataframe.rb
8
+ examples/erobj.rb
9
+ ext/Converters.c
10
+ ext/Converters.h
11
+ ext/R_eval.c
12
+ ext/R_eval.h
13
+ ext/extconf.rb
14
+ ext/robj.c
15
+ ext/rsruby.c
16
+ ext/rsruby.h
17
+ lib/rsruby.rb
18
+ lib/rsruby/dataframe.rb
19
+ lib/rsruby/erobj.rb
20
+ lib/rsruby/robj.rb
21
+ test/table.txt
22
+ test/tc_array.rb
23
+ test/tc_boolean.rb
24
+ test/tc_cleanup.rb
25
+ test/tc_eval.rb
26
+ test/tc_extensions.rb
27
+ test/tc_init.rb
28
+ test/tc_io.rb
29
+ test/tc_library.rb
30
+ test/tc_modes.rb
31
+ test/tc_robj.rb
32
+ test/tc_sigint.rb
33
+ test/tc_to_r.rb
34
+ test/tc_to_ruby.rb
35
+ test/tc_util.rb
36
+ test/tc_vars.rb
37
+ test/test_all.rb
data/README.txt ADDED
@@ -0,0 +1,96 @@
1
+ == Introduction
2
+
3
+ RSRuby is a bridge library for Ruby giving Ruby developers access to the full R statistical programming environment. RSRuby embeds a full R interpreter inside the running Ruby script, allowing R methods to be called and data passed between the Ruby script and the R interpreter. Most data conversion is handled automatically, but user-definable conversion routines can also be written to handle any R or Ruby class.
4
+
5
+ RSRuby is a partial conversion of RPy[http://rpy.sourceforge.net/], and shares the same goals of robustness, ease of use and speed. The current version is stable and passes 90% of the RPy test suite. Some conversion and method calling semantics differ between RPy and RSRuby (largely due to the differences between Python and Ruby), but they are now largely similar in functonality.
6
+
7
+ Major things to be done in the future include proper handling of OS signals, user definable I/O functions, improved DataFrame support and inevitable bug fixes.
8
+
9
+ == Installation
10
+
11
+ A working R installation is required. R must have been built with the '--enable-R-shlib' option enabled to provide the R shared library used by RSRuby.
12
+
13
+ Ensure the R_HOME environment variable is set appropriately. E.g.:
14
+
15
+ R_HOME=/usr/lib/R (on Ubuntu Linux)
16
+ R_HOME=/Library/Frameworks/R.framework/Resources (on OS X)
17
+
18
+ An RSRuby gem is available as well as a package using setup.rb. In each case the installation requires the location of your R library to compile the extension. This is usually the same as R_HOME. If you download the setup.rb package use these incantations:
19
+
20
+ ruby setup.rb config -- --with-R-dir=$R_HOME
21
+ ruby setup.rb setup
22
+ ruby setup.rb install
23
+
24
+ Using gems it is almost the same:
25
+
26
+ gem install rsruby -- --with-R-dir=$R_HOME
27
+
28
+ If RSRuby does not compile correctly you may need to configure the path to the R library, any one of the following should be sufficient:
29
+
30
+ o Put the following line in your .bashrc (or equivalent):
31
+
32
+ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:RHOME/bin
33
+
34
+ o or, make a link to RHOME/bin/libR.so in /usr/local/lib or /usr/lib, then run 'ldconfig'.
35
+
36
+ o or, edit the file /etc/ld.so.conf, add the following line and then run 'ldconfig':
37
+
38
+ RHOME/bin
39
+
40
+ == Documentation
41
+
42
+ There are a few sources of documentation for RSRuby, though the manual should be considered the authoritative text.
43
+
44
+ Manual:: The manual[http://web.kuicr.kyoto-u.ac.jp/~alexg/rsruby/manual.pdf] has most of the comprehensive information on calling R functions and the conversion system.
45
+ Examples:: A few example scripts are included in the distribution:
46
+ * Using Arrayfields[link:files/examples/arrayfields_rb.html] instead of Hash for named lists/vectors.
47
+ * Using the Bioconductor[link:files/examples/bioc_rb.html] library.
48
+ * An example[link:files/examples/dataframe_rb.html] using the DataFrame class.
49
+ * An example[link:files/examples/erobj_rb.html] using the ERObj class.
50
+ Tests:: The test scripts also show several usage examples.
51
+
52
+ Finally, here is a very quick and simple example:
53
+
54
+ #Initialize R
55
+ require 'rsruby'
56
+
57
+ #RSRuby uses Singleton design pattern so call instance rather
58
+ #than new
59
+ r = RSRuby.instance
60
+ #Call R functions on the r object
61
+ data = r.rnorm(100)
62
+ r.plot(data)
63
+ sleep(2)
64
+ #Call with named args
65
+ r.plot({'x' => data,
66
+ 'y' => data,
67
+ 'xlab' => 'test',
68
+ 'ylab' => 'test'})
69
+ sleep(2)
70
+
71
+ == License
72
+
73
+ Copyright (C) 2006 Alex Gutteridge
74
+
75
+ The Original Code is the RPy python module.
76
+
77
+ The Initial Developer of the Original Code is Walter Moreira.
78
+ Portions created by the Initial Developer are Copyright (C) 2002
79
+ the Initial Developer. All Rights Reserved.
80
+
81
+ Contributor(s):
82
+ Gregory R. Warnes <greg@warnes.net> (RPy Maintainer)
83
+
84
+ This library is free software; you can redistribute it and/or
85
+ modify it under the terms of the GNU Lesser General Public
86
+ License as published by the Free Software Foundation; either
87
+ version 2.1 of the License, or (at your option) any later version.
88
+
89
+ This library is distributed in the hope that it will be useful,
90
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
91
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
92
+ Lesser General Public License for more details.
93
+
94
+ You should have received a copy of the GNU Lesser General Public
95
+ License along with this library; if not, write to the Free Software
96
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
@@ -1,36 +1,52 @@
1
- require 'rubygems'
2
- require_gem 'arrayfields'
3
- require 'rsruby'
1
+ #==Synopsis
2
+ #
3
+ #This example shows the use of custom converters to change the default
4
+ #RSRuby behaviour. Normally RSRuby converts an R list or vector with the
5
+ #name attribute to a Ruby Hash. Ruby Hashes do not conserve order however
6
+ #unlike the R datatypes.
7
+ #
8
+ #To better replicate the R behaviour, this code uses the arrayfields library
9
+ #(available as a gem) and the RSRuby Proc conversion mode to create named
10
+ #Arrays which preserve order.
11
+ #
12
+ #NB: You can run this file like a normal Ruby script. I use some post-
13
+ #processing to allow me to add the source to RDoc.
14
+ #
15
+ # require 'arrayfields'
16
+ # require 'rsruby'
17
+ #
18
+ #First we generate a Proc that will return true if we have an R object
19
+ #that has the 'names' attribute set:
20
+ #
21
+ # test_proc = lambda{|x| !(RSRuby.instance.attr(x,'names').nil?) }
22
+ #
23
+ #The next Proc takes the R object and generates a new Array with fields
24
+ #set appropriately:
25
+ #
26
+ # conv_proc = lambda{|x|
27
+ # hash = x.to_ruby
28
+ # array = []
29
+ # array.fields = RSRuby.instance.attr(x,'names')
30
+ # RSRuby.instance.attr(x,'names').each{|f| array[f] = hash[f]}
31
+ # return array
32
+ # }
33
+ #
34
+ #Next we start R, set the t.test function to use Proc conversion and
35
+ #add our Procs to the proc_table Hash.
36
+ #
37
+ # r = RSRuby.instance
38
+ # r.t_test.autoconvert(RSRuby::PROC_CONVERSION)
39
+ # r.proc_table[test_proc] = conv_proc
40
+ #
41
+ #The return values from t.test are now Arrays rather than Hashes:
42
+ #
43
+ # ttest = r.t_test([1,2,3])
44
+ # puts ttest.class
45
+ # ttest.each_pair do |field,val|
46
+ # puts "#{field} - #{val}"
47
+ # end
48
+ # puts ttest[1..3]
4
49
 
5
- test_proc = lambda{|x|
6
- r = RSRuby.instance
7
- names = r.attr(x,'names')
8
- if names.nil?
9
- return false
10
- else
11
- return true
12
- end
13
- }
14
-
15
- conv_proc = lambda{|x|
16
- r = RSRuby.instance
17
- names = r.attr(x,'names')
18
- hash = x.to_ruby
19
- array = []
20
- array.fields = names
21
- names.each do |field|
22
- array[field] = hash[field]
23
- end
24
- return array
25
- }
26
-
27
- r = RSRuby.instance
28
- r.t_test.autoconvert(RSRuby::PROC_CONVERSION)
29
- r.proc_table[test_proc] = conv_proc
30
-
31
- ttest = r.t_test([1,2,3])
32
- puts ttest.class
33
- ttest.each_pair do |field,val|
34
- puts "#{field} - #{val}"
50
+ if __FILE__ == $0
51
+ eval(IO.read($0).gsub(/^\#\s\s/,''))
35
52
  end
36
- puts ttest[1..3]
data/examples/bioc.rb CHANGED
@@ -1,99 +1,35 @@
1
- require 'rsruby'
2
-
3
- class ERObj
4
-
5
- @@x = 1
6
-
7
- def initialize(robj)
8
- @robj = robj
9
- @r = RSRuby.instance
10
- end
11
-
12
- def as_r
13
- @robj.as_r
14
- end
15
-
16
- def lcall(args)
17
- @robj.lcall(args)
18
- end
19
-
20
- def to_s
21
-
22
- @@x += 1
23
-
24
- mode = RSRuby.get_default_mode
25
- RSRuby.set_default_mode(RSRuby::NO_CONVERSION)
26
- a = @r.textConnection("tmpobj#{@@x}",'w')
27
-
28
- RSRuby.set_default_mode(RSRuby::BASIC_CONVERSION)
29
- @r.sink(:file => a, :type => 'output')
30
- @r.print_(@robj)
31
- @r.sink.call()
32
- @r.close_connection(a)
33
-
34
- str = @r["tmpobj#{@@x}"].join("\n")
35
-
36
- RSRuby.set_default_mode(mode)
37
-
38
- return str
39
-
40
- end
41
-
42
- def method_missing(attr)
43
- mode = RSRuby.get_default_mode
44
- RSRuby.set_default_mode(RSRuby::BASIC_CONVERSION)
45
- e = @r['$'].call(@robj,attr.to_s)
46
- RSRuby.set_default_mode(mode)
47
- return e
48
- end
49
-
1
+ #==Synopsis
2
+ #
3
+ #This example shows the use of the DataFrame class and eval_R to execute some
4
+ #Bioconductor code
5
+ #
6
+ # require 'rsruby'
7
+ # require 'dataframe'
8
+ #
9
+ # r = RSRuby.instance
10
+ #
11
+ #First we setup the class_table Hash to convert dataframes to Ruby DataFrames
12
+ #
13
+ # r.class_table['data.frame'] = lambda{|x| DataFrame.new(x)}
14
+ # RSRuby.set_default_mode(RSRuby::CLASS_CONVERSION)
15
+ #
16
+ #Then we load the Bioconductor affy library and use eval_R to run some affy
17
+ #code
18
+ #
19
+ # r.library('affy')
20
+ #
21
+ # r.eval_R("mydata <- ReadAffy()")
22
+ # r.eval_R("eset.rma <- rma(mydata)")
23
+ # r.eval_R("eset.pma <- mas5calls(mydata)")
24
+ #
25
+ #frame = r.eval_R("data.frame(exprs(eset.rma), exprs(eset.pma), se.exprs(eset.pma))")
26
+ #
27
+ # puts frame.class
28
+ # puts frame.rows.join(" ")
29
+ # puts frame.columns.join(" ")
30
+ #
31
+ # puts frame.send('COLD_12H_SHOOT_REP1.cel'.to_sym)
32
+
33
+ if __FILE__ == $0
34
+ eval(IO.read($0).gsub(/^\#\s\s/,''))
50
35
  end
51
-
52
- class DataFrame < ERObj
53
-
54
- def rows
55
- return @r.attr(@robj, 'row.names')
56
- end
57
-
58
- def columns
59
- cols = @r.colnames(@robj)
60
- cols = [cols] unless cols.class == 'Array'
61
- return cols
62
- end
63
-
64
- def method_missing(attr)
65
- attr = attr.to_s
66
- mode = RSRuby.get_default_mode
67
- RSRuby.set_default_mode(RSRuby::BASIC_CONVERSION)
68
- column_names = @r.colnames(@robj)
69
- if attr == column_names or column_names.include?(attr)
70
- RSRuby.set_default_mode(mode)
71
- return @r['$'].call(@robj,attr.to_s)
72
- end
73
-
74
- #? Not sure what here...
75
- RSRuby.set_default_mode(mode)
76
- return super(attr)
77
-
78
- end
79
-
80
- end
81
-
82
- r = RSRuby.instance
83
-
84
- r.class_table['data.frame'] = lambda{|x| DataFrame.new(x)}
85
-
86
- r.library('affy')
87
-
88
- r.eval_R("mydata <- ReadAffy()")
89
- r.eval_R("eset.rma <- rma(mydata)")
90
- r.eval_R("eset.pma <- mas5calls(mydata)")
91
-
92
- RSRuby.set_default_mode(RSRuby::CLASS_CONVERSION)
93
- frame = r.eval_R("data.frame(exprs(eset.rma), exprs(eset.pma), se.exprs(eset.pma))")
94
-
95
- puts frame.class
96
- puts frame.rows.join(" ")
97
- puts frame.columns.join(" ")
98
-
99
- puts frame.send('COLD_12H_SHOOT_REP1.cel'.to_sym)
@@ -1,15 +1,35 @@
1
- require 'rsruby'
2
- require 'rsruby/dataframe'
1
+ #==Synopsis
2
+ #
3
+ #This example shows the use of the Class conversion system to convert
4
+ #dataframes into the Ruby DataFrame class
5
+ #
6
+ # require 'rsruby'
7
+ # require 'rsruby/dataframe'
8
+ #
9
+ # r = RSRuby.instance
10
+ #
11
+ #Here we just set up a simple class table that returns a new DataFrame
12
+ #object when a dataframe is returned by R
13
+ #
14
+ # r.class_table['data.frame'] = lambda{|x| DataFrame.new(x)}
15
+ # RSRuby.set_default_mode(RSRuby::CLASS_CONVERSION)
16
+ #
17
+ #We then create a dataframe object to test the conversion
18
+ # e = r.as_data_frame(:x => {'foo' => [4,5,6], 'bar' => ['X','Y','Z']})
19
+ #
20
+ #Using some of the ERObj and DataFrame class capabilities we can access the
21
+ #dataframe data in various ways
22
+ #
23
+ # puts e
24
+ # puts e.foo.join(" ")
25
+ # puts e.bar.join(" ")
26
+ # puts e.rows.join(" ")
27
+ # puts e.columns.join(" ")
28
+ #
29
+ # puts e.baz.join(" ")
30
+ #
31
+ # puts e['foo'].join(" ")
3
32
 
4
- r.class_table['data.frame'] = lambda{|x| DataFrame.new(x)}
5
- RSRuby.set_default_mode(RSRuby::CLASS_CONVERSION)
6
-
7
- #slight kludge here need to use this form because of the
8
- #calling with keywords semantics are different to RPy
9
- e = r.as_data_frame(:x => {'foo' => [4,5,6], 'bar' => ['X','Y','Z']})
10
-
11
- puts e
12
- puts e.foo.join(" ")
13
- puts e.bar.join(" ")
14
- puts e.rows.join(" ")
15
- puts e.columns.join(" ")
33
+ if __FILE__ == $0
34
+ eval(IO.read($0).gsub(/^\#\s\s/,''))
35
+ end
data/examples/erobj.rb CHANGED
@@ -1,16 +1,30 @@
1
- require 'rsruby'
2
- require 'rsruby/erobj'
1
+ #==Synopsis
2
+ #
3
+ #In this example we intercept the conversion system using the proc conversion
4
+ #mode. Instead of converting, every object returned by R is converted to an
5
+ #ERObj
6
+ #
7
+ # require 'rsruby'
8
+ # require 'rsruby/erobj'
9
+ #
10
+ # r = RSRuby.instance
11
+ #
12
+ #Setting the proc table up with a Proc which always returns true serves to
13
+ #intercept the RSRuby conversion system. The conversion system is bypassed
14
+ #into the second Proc
15
+ #
16
+ # r.proc_table[lambda{|x| true}] = lambda{|x| ERObj.new(x)}
17
+ # RSRuby.set_default_mode(RSRuby::PROC_CONVERSION)
18
+ #
19
+ # e = r.t_test([1,2,3,4,5,6])
20
+ #
21
+ #One feature of ERObj is that they output the same string representation
22
+ #as R. We can also access attributes of the R object
23
+ #
24
+ # puts e
25
+ # puts "t value: #{e.statistic['t']}"
26
+ #
3
27
 
4
- r = RSRuby.instance
5
- r.proc_table[lambda{|x| true}] = lambda{|x| ERObj.new(x)}
6
- RSRuby.set_default_mode(RSRuby::PROC_CONVERSION)
7
-
8
- e = r.t_test([1,2,3,4,5,6])
9
-
10
- puts e
11
- puts "t value: #{e.statistic['t']}"
12
-
13
- f = r.t_test([1,2,3])
14
-
15
- puts f
16
- puts "t value: #{f.statistic['t']}"
28
+ if __FILE__ == $0
29
+ eval(IO.read($0).gsub(/^\#\s\s/,''))
30
+ end