alexgutteridge-rsruby 0.5

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest.txt ADDED
@@ -0,0 +1,39 @@
1
+ History.txt
2
+ License.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile.rb
6
+ examples/arrayfields.rb
7
+ examples/bioc.rb
8
+ examples/dataframe.rb
9
+ examples/erobj.rb
10
+ ext/Converters.c
11
+ ext/Converters.h
12
+ ext/R_eval.c
13
+ ext/R_eval.h
14
+ ext/extconf.rb
15
+ ext/robj.c
16
+ ext/rsruby.c
17
+ ext/rsruby.h
18
+ lib/rsruby.rb
19
+ lib/rsruby/dataframe.rb
20
+ lib/rsruby/erobj.rb
21
+ lib/rsruby/robj.rb
22
+ test/table.txt
23
+ test/tc_array.rb
24
+ test/tc_boolean.rb
25
+ test/tc_cleanup.rb
26
+ test/tc_eval.rb
27
+ test/tc_extensions.rb
28
+ test/tc_init.rb
29
+ test/tc_io.rb
30
+ test/tc_library.rb
31
+ test/tc_matrix.rb
32
+ test/tc_modes.rb
33
+ test/tc_robj.rb
34
+ test/tc_sigint.rb
35
+ test/tc_to_r.rb
36
+ test/tc_to_ruby.rb
37
+ test/tc_util.rb
38
+ test/tc_vars.rb
39
+ 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
data/Rakefile.rb ADDED
@@ -0,0 +1,153 @@
1
+ require 'hoe'
2
+
3
+ $LOAD_PATH.unshift("./lib")
4
+ $LOAD_PATH.unshift("./ext")
5
+
6
+ gem_name = RUBY_PLATFORM !~ /mswin32$/ ? "rsruby" : "rsrubywin"
7
+ hoe = Hoe.new(gem_name,'0.5') do |p|
8
+
9
+ p.author = "Alex Gutteridge"
10
+ p.email = "ag357@cam.ac.uk"
11
+ p.url = "http://web.kuicr.kyoto-u.ac.jp/~alexg/rsruby/"
12
+
13
+ p.description = p.paragraphs_of("README.txt",1..3)[0]
14
+ p.summary = p.paragraphs_of("README.txt",1)[0]
15
+ p.changes = p.paragraphs_of("History.txt",0..1).join("\n\n")
16
+
17
+ p.clean_globs = ["ext/*.o","ext/*.so","ext/Makefile","ext/mkmf.log","**/*~","email.txt","manual.{aux,log,out,toc,pdf}"]
18
+
19
+ p.rdoc_pattern = /(^lib\/.*\.rb$|^examples\/.*\.rb$|^README|^History|^License)/
20
+
21
+ p.spec_extras = {
22
+ :extensions => RUBY_PLATFORM !~ /mswin32$/ ? ['ext/extconf.rb'] : [],
23
+ :require_paths => ['lib','test','ext'],
24
+ :has_rdoc => true,
25
+ :extra_rdoc_files => ["README.txt","History.txt","License.txt"] + FileList["examples/*"],
26
+ :rdoc_options => ["--exclude", "test/*", "--main", "README.txt", "--inline-source"]
27
+ }
28
+
29
+ task :setup_rb_package => [:clean, :package] do
30
+
31
+ package_dir = "#{p.name}-#{p.version}"
32
+ cp("setup.rb","pkg/#{package_dir}")
33
+ #cp("manual.pdf","pkg/#{package_dir}")
34
+
35
+ Dir.chdir("pkg")
36
+ system("tar -czf #{p.name}-#{p.version}.tgz #{package_dir}")
37
+ Dir.chdir("..")
38
+
39
+ end
40
+
41
+ end
42
+
43
+ hoe.spec.dependencies.delete_if{|dep| dep.name == "hoe"}
44
+ if RUBY_PLATFORM =~ /mswin32$/
45
+ # add the precompiled rsruby_c.so into the gemspec
46
+ hoe.spec.files = hoe.spec.files + ["ext/rsruby_c.so"]
47
+
48
+ # add the :build_extension task to :gem so that the extension gets
49
+ # built BEFORE packaging (note the task needs to occur first)
50
+ Rake.application.lookup(:gem).prerequisites.unshift(:build_extension)
51
+ end
52
+
53
+ desc "Uses extconf.rb and make to build the extension"
54
+ task :build_extension => ['ext/rsruby_c.so']
55
+ SRC = FileList['ext/*.c'] + FileList['ext/*.h']
56
+ file 'ext/rsruby_c.so' => SRC do
57
+ Dir.chdir('ext')
58
+ if RUBY_PLATFORM !~ /mswin32$/
59
+ system("ruby extconf.rb -- --with-R-dir=$R_HOME --with-R-include=/usr/share/R/include/")
60
+ system("make")
61
+ else
62
+ # Windows-specific build that does not use extconf.rb or make
63
+ # This build was designed using the default One-Click Installer
64
+ # for Windows (1.8.6-25) and MinGW (5.1.3). Both are freely
65
+ # available. See the following websites for downloads and
66
+ # installation information:
67
+ #
68
+ # http://rubyforge.org/projects/rubyinstaller/
69
+ # http://www.mingw.org/
70
+ #
71
+
72
+ # TODO -
73
+ # * add checks for installation paths
74
+ # * rewrite this build in terms of rake rules? (or at least check
75
+ # so that up-to-date files are not rebuilt)
76
+ # * add configuration options a-la extconf.rb
77
+
78
+ # Note: here I use slashes '/' rather than backslashes '\' in the paths.
79
+ # If you enter the gcc command into the command prompt, you do NOT
80
+ # need to use the *nix-style paths. Here it's necessary so the backslashes
81
+ # aren't treated as character escapes in the ruby strings.
82
+ ruby_install_dir = ENV['RUBY_INSTALL_DIR'] || "C:/ruby"
83
+ ruby_headers_dir = "#{ruby_install_dir}/lib/ruby/1.8/i386-mswin32"
84
+ ruby_lib_dir = "#{ruby_install_dir}/lib"
85
+
86
+ r_install_dir = ENV['R_INSTALL_DIR'] || "C:/Program Files/R/R-2.6.0"
87
+ r_headers_dir = "#{r_install_dir}/include"
88
+ r_lib_dir = "#{r_install_dir}/bin"
89
+
90
+ # These defines are all added for a clean compile. I'm not sure if
91
+ # setting these flags is appropriate, but they do work.
92
+ # HAVE_R_H:: extconf.rb includes this flag
93
+ # HAVE_ISINF:: prevents "isinf" redefinition
94
+ # _MSC_VER:: prevents "MSC version unmatch" error -- it may not be smart to bypass this check
95
+ # STRICT_R_HEADERS:: prevents "ERROR" redefinition
96
+ defines = "-DHAVE_R_H -DHAVE_ISINF -D_MSC_VER=1200 -DSTRICT_R_HEADERS"
97
+
98
+ # check required files exist
99
+ [ruby_headers_dir, ruby_lib_dir].each do |dir|
100
+ next if File.exists?(dir)
101
+ raise %Q{
102
+ Build Error:
103
+ ruby directory does not exist (#{dir})
104
+ Try setting RUBY_INSTALL_DIR to the ruby installation directory.
105
+
106
+ }
107
+ end
108
+
109
+ [r_headers_dir, r_lib_dir].each do |dir|
110
+ next if File.exists?(dir)
111
+ raise %Q{
112
+ Build Error:
113
+ R directory does not exist (#{dir})
114
+ Try setting R_INSTALL_DIR to the R installation directory.
115
+
116
+ }
117
+ end
118
+
119
+ OBJ = SRC.collect do |src|
120
+ next unless File.extname(src) == ".c"
121
+
122
+ # at this point the src files are like 'ext/src.c'
123
+ src = File.basename(src)
124
+
125
+ # compile each source file, using the same flags as extconf.rb
126
+ # notice the quotes encapsulating the include paths, so that
127
+ # spaces are allowed (as in the R default install path)
128
+ sh( %Q{gcc -I. -I"#{ruby_headers_dir}" -I"#{r_headers_dir}" #{defines} -g -O2 -c #{src}} )
129
+
130
+ # double duty... collect the .o filenames
131
+ File.basename(src).chomp(".c") + ".o"
132
+ end.compact
133
+
134
+ # same notes as extconf.rb
135
+ sh( %Q{gcc -shared -s -L. -Wl,--enable-auto-image-base,--enable-auto-import,--export-all -L"#{ruby_lib_dir}" -L"#{r_lib_dir}" -o rsruby_c.so #{OBJ.join(" ")} -lmsvcrt-ruby18 -lR -lwsock32})
136
+ end
137
+ Dir.chdir('..')
138
+ end
139
+
140
+ task :test => [:build_extension]
141
+
142
+ desc "Build PDF manual"
143
+ task :build_manual => ["manual.pdf"]
144
+ file "manual.pdf" => ["manual.tex"] do
145
+ out = 'Rerun'
146
+ while out.match(/Rerun/)
147
+ out = `pdflatex manual.tex`
148
+ end
149
+ end
150
+
151
+ task :build_manual_clean => [:build_manual] do
152
+ system("rm manual.{aux,log,out,toc}")
153
+ end
@@ -0,0 +1,52 @@
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]
49
+
50
+ if __FILE__ == $0
51
+ eval(IO.read($0).gsub(/^\#\s\s/,''))
52
+ end
data/examples/bioc.rb ADDED
@@ -0,0 +1,35 @@
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/,''))
35
+ end
@@ -0,0 +1,35 @@
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(" ")
32
+
33
+ if __FILE__ == $0
34
+ eval(IO.read($0).gsub(/^\#\s\s/,''))
35
+ end
data/examples/erobj.rb ADDED
@@ -0,0 +1,30 @@
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
+ #
27
+
28
+ if __FILE__ == $0
29
+ eval(IO.read($0).gsub(/^\#\s\s/,''))
30
+ end