rsruby 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +102 -0
- data/examples/arrayfields.rb +36 -0
- data/examples/bioc.rb +99 -0
- data/examples/dataframe.rb +15 -0
- data/examples/erobj.rb +16 -0
- data/ext/rsruby/Converters.c +657 -0
- data/ext/rsruby/Converters.h +74 -0
- data/ext/rsruby/R_eval.c +138 -0
- data/ext/rsruby/R_eval.h +40 -0
- data/ext/rsruby/extconf.rb +20 -0
- data/ext/rsruby/robj.c +169 -0
- data/ext/rsruby/rsruby.c +183 -0
- data/ext/rsruby/rsruby.h +80 -0
- data/lib/rsruby.rb +361 -0
- data/lib/rsruby/dataframe.rb +77 -0
- data/lib/rsruby/erobj.rb +97 -0
- data/lib/rsruby/robj.rb +58 -0
- data/test/tc_array.rb +58 -0
- data/test/tc_boolean.rb +27 -0
- data/test/tc_cleanup.rb +22 -0
- data/test/tc_eval.rb +15 -0
- data/test/tc_init.rb +0 -0
- data/test/tc_io.rb +60 -0
- data/test/tc_library.rb +20 -0
- data/test/tc_modes.rb +212 -0
- data/test/tc_robj.rb +87 -0
- data/test/tc_sigint.rb +10 -0
- data/test/tc_to_r.rb +146 -0
- data/test/tc_to_ruby.rb +155 -0
- data/test/tc_util.rb +19 -0
- data/test/tc_vars.rb +28 -0
- metadata +89 -0
data/ext/rsruby/rsruby.h
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
/*
|
2
|
+
* == Author
|
3
|
+
* Alex Gutteridge
|
4
|
+
*
|
5
|
+
* == Copyright
|
6
|
+
*Copyright (C) 2006 Alex Gutteridge
|
7
|
+
*
|
8
|
+
* The Original Code is the RPy python module.
|
9
|
+
*
|
10
|
+
* The Initial Developer of the Original Code is Walter Moreira.
|
11
|
+
* Portions created by the Initial Developer are Copyright (C) 2002
|
12
|
+
* the Initial Developer. All Rights Reserved.
|
13
|
+
*
|
14
|
+
* Contributor(s):
|
15
|
+
* Gregory R. Warnes <greg@warnes.net> (RPy Maintainer)
|
16
|
+
*
|
17
|
+
*This library is free software; you can redistribute it and/or
|
18
|
+
*modify it under the terms of the GNU Lesser General Public
|
19
|
+
*License as published by the Free Software Foundation; either
|
20
|
+
*version 2.1 of the License, or (at your option) any later version.
|
21
|
+
*
|
22
|
+
*This library is distributed in the hope that it will be useful,
|
23
|
+
*but WITHOUT ANY WARRANTY; without even the implied warranty of
|
24
|
+
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
25
|
+
*Lesser General Public License for more details.
|
26
|
+
*
|
27
|
+
*You should have received a copy of the GNU Lesser General Public
|
28
|
+
*License along with this library; if not, write to the Free Software
|
29
|
+
*Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
30
|
+
*/
|
31
|
+
|
32
|
+
#ifndef R_RUBY_MAIN
|
33
|
+
#define R_RUBY_MAIN
|
34
|
+
|
35
|
+
#include "ruby.h"
|
36
|
+
|
37
|
+
#include "R.h"
|
38
|
+
#include "Rdefines.h"
|
39
|
+
#include "Rinternals.h"
|
40
|
+
#include "Rdefines.h"
|
41
|
+
#include "Rdevices.h"
|
42
|
+
|
43
|
+
#include "signal.h"
|
44
|
+
|
45
|
+
#include "R_eval.h"
|
46
|
+
#include "Converters.h"
|
47
|
+
|
48
|
+
#define MAXIDSIZE 256
|
49
|
+
|
50
|
+
#define NO_CONVERSION 0
|
51
|
+
#define VECTOR_CONVERSION 1
|
52
|
+
#define BASIC_CONVERSION 2
|
53
|
+
#define CLASS_CONVERSION 3
|
54
|
+
#define PROC_CONVERSION 4
|
55
|
+
|
56
|
+
#define TOP_MODE 4
|
57
|
+
|
58
|
+
/* Missing definitions from Rinterface.h or RStartup.h */
|
59
|
+
# define CleanEd Rf_CleanEd
|
60
|
+
extern void CleanEd(void);
|
61
|
+
extern int R_CollectWarnings;
|
62
|
+
# define PrintWarnings Rf_PrintWarnings
|
63
|
+
extern void PrintWarnings(void);
|
64
|
+
|
65
|
+
void Init_rsruby();
|
66
|
+
|
67
|
+
void init_R(int argc, char *argv[0]);
|
68
|
+
void r_finalize(void);
|
69
|
+
|
70
|
+
static SEXP RecursiveRelease(SEXP obj, SEXP list);
|
71
|
+
static void Robj_dealloc(VALUE self);
|
72
|
+
|
73
|
+
VALUE shutdown(VALUE self);
|
74
|
+
VALUE get_fun(VALUE self, VALUE name);
|
75
|
+
VALUE rr_init(VALUE self);
|
76
|
+
|
77
|
+
VALUE RObj_lcall(VALUE self, VALUE args);
|
78
|
+
VALUE RObj_to_ruby(VALUE self, VALUE args);
|
79
|
+
|
80
|
+
#endif
|
data/lib/rsruby.rb
ADDED
@@ -0,0 +1,361 @@
|
|
1
|
+
#== Synopsis
|
2
|
+
#
|
3
|
+
#This class provides the ability to embed a full R
|
4
|
+
#interpreter inside a running Ruby script. R methods can
|
5
|
+
#then be called from the Ruby script and data passed between the
|
6
|
+
#R interpreter and the Ruby script. The code is based on a conversion
|
7
|
+
#of the RSPerl[http://www.omegahat.org/RSPerl/] and RPy[http://rpy.sourceforge.net/]
|
8
|
+
#modules which provide similar (and more) functionality for Perl and Python
|
9
|
+
#respectively.
|
10
|
+
#
|
11
|
+
#The main RSRuby class has Singleton module mixed in. This ensures that only
|
12
|
+
#one R interpreter is running in a script at any one time and that the
|
13
|
+
#interpreter can always be found. The embedded R interpreter is started by
|
14
|
+
#calling RSRuby.instance (See the RSRuby class for details). The returned
|
15
|
+
#RSRuby object represents the R interpreter and R functions are called by
|
16
|
+
#calling methods on this object.
|
17
|
+
#
|
18
|
+
#== Usage
|
19
|
+
#
|
20
|
+
# require 'rsruby'
|
21
|
+
#
|
22
|
+
# r = RSRuby.instance
|
23
|
+
# puts r.sum(1,2,3)
|
24
|
+
#
|
25
|
+
#Converting between R and Ruby data types is handled in a similar way to
|
26
|
+
#RPy and is explained in more detail in the manual (see Converters.c for the
|
27
|
+
#gory details).
|
28
|
+
#
|
29
|
+
#The default conversion system mapping between R types and Ruby classes is
|
30
|
+
#summarised here:
|
31
|
+
#
|
32
|
+
# - R Logicals (true/false) <=> Ruby true/false
|
33
|
+
# - R Integers <=> Ruby Fixnum/Bignum
|
34
|
+
# - R Real <=> Ruby Float
|
35
|
+
# - R Complex <=> Ruby Complex
|
36
|
+
# - R String <=> Ruby String
|
37
|
+
# - R Vector <=> Ruby Array or Hash
|
38
|
+
# - R List <=> Ruby Array or Hash
|
39
|
+
# - R Array <=> Ruby Array or Hash
|
40
|
+
# - R 'other' <=> Ruby RObj
|
41
|
+
#
|
42
|
+
#While this generally works fine for simple data structures, more complicated
|
43
|
+
#structures can loose information when converted to Ruby. Clever use of the
|
44
|
+
#more complicated custom conversion modes can usually avoid this.
|
45
|
+
#
|
46
|
+
#As shown above, calling R methods can be done by calling the same method
|
47
|
+
#on the RSRuby object. Some R methods contain '.' and other characters
|
48
|
+
#forbidden in Ruby method names. To call these methods substitute '_' for '.':
|
49
|
+
#
|
50
|
+
#Sample usage (to call R method 'as.list'):
|
51
|
+
#
|
52
|
+
# require 'rsruby'
|
53
|
+
#
|
54
|
+
# r = RSRuby.instance
|
55
|
+
# puts r.as_list([1,2,3])
|
56
|
+
#
|
57
|
+
#If a Hash is the last argument to an RSRuby method call then the hash is
|
58
|
+
#interpreted as a list of named arguments to the corresponding R function.
|
59
|
+
#Argument names can be given as Strings or Symbols. Argument order is not
|
60
|
+
#maintained in this case (because order is not maintained in Hashes). If
|
61
|
+
#named arguments and order are required then there is the lcall syntax where
|
62
|
+
#arguments are given as an array of two member arrays (where each two member
|
63
|
+
#array represents a name/argument pair). lcall is a method defined in the
|
64
|
+
#RObj class which represents functions and other non-convertible R objects.
|
65
|
+
#
|
66
|
+
#Calling an R method with no arguments returns the method object itself - it
|
67
|
+
#does not call the method. This may be changed in the future as it is somewhat
|
68
|
+
#confusing. However, the returned object can then be called or 'lcall'ed as
|
69
|
+
#required. It is also possible to return R variables in this way:
|
70
|
+
#
|
71
|
+
#E.g.
|
72
|
+
#
|
73
|
+
# require 'rsruby'
|
74
|
+
#
|
75
|
+
# r = RSRuby.instance
|
76
|
+
# norm = r.rnorm
|
77
|
+
# norm_dist = norm.call(100)
|
78
|
+
#
|
79
|
+
# r.plot(norm_dist,
|
80
|
+
# {:ylab => "TestY"})
|
81
|
+
# sleep(2)
|
82
|
+
#
|
83
|
+
#
|
84
|
+
#The final way to execute R code is to just evaluate a complete R expression
|
85
|
+
#The eval_R method provides this functionality. Pass a String to the method to
|
86
|
+
#see it evaluated by R:
|
87
|
+
#
|
88
|
+
# require 'rsruby'
|
89
|
+
#
|
90
|
+
# r = RSRuby.instance
|
91
|
+
# r.eval_R("a=43")
|
92
|
+
# puts r.a
|
93
|
+
#
|
94
|
+
#As an alternative to the method syntax, R objects and functions can be
|
95
|
+
#returned using []. This is required for weird R methods such as '$' or '[[':
|
96
|
+
#
|
97
|
+
# require 'rsruby'
|
98
|
+
#
|
99
|
+
# r = RSRuby.instance
|
100
|
+
# r.eval_R("a=43")
|
101
|
+
# puts r['a']
|
102
|
+
#
|
103
|
+
#R libraries can be loaded using the library method. Just provide the library
|
104
|
+
#name as a String:
|
105
|
+
#
|
106
|
+
# require 'rsruby'
|
107
|
+
#
|
108
|
+
# r = RSRuby.instance
|
109
|
+
# r.library("library_name")
|
110
|
+
#
|
111
|
+
#== Author
|
112
|
+
#Alex Gutteridge
|
113
|
+
#
|
114
|
+
#== Copyright
|
115
|
+
#Copyright (C) 2006 Alex Gutteridge
|
116
|
+
#
|
117
|
+
#The Original Code is the RPy python module.
|
118
|
+
#
|
119
|
+
#The Initial Developer of the Original Code is Walter Moreira.
|
120
|
+
#Portions created by the Initial Developer are Copyright (C) 2002
|
121
|
+
#the Initial Developer. All Rights Reserved.
|
122
|
+
#
|
123
|
+
#Contributor(s):
|
124
|
+
#Gregory R. Warnes <greg@warnes.net> (RPy Maintainer)
|
125
|
+
#
|
126
|
+
#This library is free software; you can redistribute it and/or
|
127
|
+
#modify it under the terms of the GNU Lesser General Public
|
128
|
+
#License as published by the Free Software Foundation; either
|
129
|
+
#version 2.1 of the License, or (at your option) any later version.
|
130
|
+
#
|
131
|
+
#This library is distributed in the hope that it will be useful,
|
132
|
+
#but WITHOUT ANY WARRANTY; without even the implied warranty of
|
133
|
+
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
134
|
+
#Lesser General Public License for more details.
|
135
|
+
#
|
136
|
+
#You should have received a copy of the GNU Lesser General Public
|
137
|
+
#License along with this library; if not, write to the Free Software
|
138
|
+
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
139
|
+
|
140
|
+
require 'rsruby/robj'
|
141
|
+
require 'rsruby.so'
|
142
|
+
require 'singleton'
|
143
|
+
|
144
|
+
require 'complex'
|
145
|
+
|
146
|
+
class RException < RuntimeError
|
147
|
+
end
|
148
|
+
|
149
|
+
class RSRuby
|
150
|
+
|
151
|
+
include Singleton
|
152
|
+
|
153
|
+
#Constants for conversion modes
|
154
|
+
TOP_CONVERSION = 4
|
155
|
+
PROC_CONVERSION = 4
|
156
|
+
CLASS_CONVERSION = 3
|
157
|
+
BASIC_CONVERSION = 2
|
158
|
+
VECTOR_CONVERSION = 1
|
159
|
+
NO_CONVERSION = 0
|
160
|
+
NO_DEFAULT = -1
|
161
|
+
|
162
|
+
alias c_initialize initialize
|
163
|
+
|
164
|
+
#Create a new RSRuby interpreter instance. The Singleton design pattern
|
165
|
+
#ensures that only one instance can be running in a script. Further
|
166
|
+
#calls to RSRuby.instance will return the original instance.
|
167
|
+
def initialize()
|
168
|
+
|
169
|
+
#Initialize in C
|
170
|
+
c_initialize
|
171
|
+
|
172
|
+
@@default_mode = NO_DEFAULT
|
173
|
+
|
174
|
+
@@class_table = {}
|
175
|
+
@@proc_table = {}
|
176
|
+
|
177
|
+
#Setup R object cache
|
178
|
+
@@cache = {}
|
179
|
+
@@cache['get'] = self.get_fun('get')
|
180
|
+
|
181
|
+
#Get constants
|
182
|
+
@@cache['TRUE'] = self.__getitem__('T')
|
183
|
+
@@cache['FALSE'] = self.__getitem__('F')
|
184
|
+
@@cache['NA'] = self.eval_R('NA')
|
185
|
+
# @@cache['NAN'] = self.eval_R('as.double(NA)')
|
186
|
+
@@cache['NaN'] = self.eval_R('NaN')
|
187
|
+
|
188
|
+
#help!
|
189
|
+
@@cache['helpfun'] = self.with_mode(NO_CONVERSION, self.__getitem__('help'))
|
190
|
+
|
191
|
+
#Catch errors
|
192
|
+
self.eval_R("options(error=expression(NULL))")
|
193
|
+
#disable errors
|
194
|
+
self.options('show.error.messages' => false)
|
195
|
+
|
196
|
+
end
|
197
|
+
|
198
|
+
#Handles method name conversion and calling of R functions
|
199
|
+
#If called without args the R function/varialbe is returned rather
|
200
|
+
#than called.
|
201
|
+
def method_missing(r_id,*args)
|
202
|
+
|
203
|
+
#Translate Ruby method call to R
|
204
|
+
robj_name = RSRuby.convert_method_name(r_id.to_s)
|
205
|
+
|
206
|
+
#Retrieve it
|
207
|
+
robj = self.__getitem__(robj_name)
|
208
|
+
|
209
|
+
#TODO perhaps this is not neccessary - always call these methods
|
210
|
+
#use the [] syntax for variables etc...
|
211
|
+
if args.length > 0
|
212
|
+
|
213
|
+
#convert arguments to lcall format
|
214
|
+
lcall_args = RSRuby.convert_args_to_lcall(args)
|
215
|
+
|
216
|
+
#Return result of calling object with lcall
|
217
|
+
#formatted args
|
218
|
+
return robj.lcall(lcall_args)
|
219
|
+
|
220
|
+
end
|
221
|
+
|
222
|
+
return robj
|
223
|
+
|
224
|
+
end
|
225
|
+
|
226
|
+
#As method_missing, but only returns the R function/object
|
227
|
+
#does not call it.
|
228
|
+
def [](r_id)
|
229
|
+
|
230
|
+
#Translate Ruby method call to R
|
231
|
+
robj_name = RSRuby.convert_method_name(r_id.to_s)
|
232
|
+
|
233
|
+
#Retrieve it
|
234
|
+
robj = self.__getitem__(robj_name)
|
235
|
+
|
236
|
+
#And return it
|
237
|
+
return robj
|
238
|
+
|
239
|
+
end
|
240
|
+
|
241
|
+
#Takes an #RObj representing an R function and sets the 'wrapping'
|
242
|
+
#mode for that function. Implemented for compatibility with RPy.
|
243
|
+
def with_mode(mode,func)
|
244
|
+
func.wrap = mode
|
245
|
+
return func
|
246
|
+
end
|
247
|
+
|
248
|
+
#Converts method names from Ruby compatible style into R style.
|
249
|
+
def RSRuby.convert_method_name(name)
|
250
|
+
if name.length > 1 and name[-1].chr == '_' and name[-2].chr != '_'
|
251
|
+
name = name[0..-2]
|
252
|
+
end
|
253
|
+
name.gsub!(/__/,'<-')
|
254
|
+
name.gsub!(/_/, '.')
|
255
|
+
return name
|
256
|
+
end
|
257
|
+
|
258
|
+
#Converts an array of arguments into lcall format. If the last element
|
259
|
+
#of the array is a Hash then the contents are interpreted as named
|
260
|
+
#arguments. lcall format is an Array of two member Arrays. Each two
|
261
|
+
#member array corresponds to a name/argument pair.
|
262
|
+
def RSRuby.convert_args_to_lcall(args)
|
263
|
+
|
264
|
+
lcall_args = []
|
265
|
+
|
266
|
+
args.each_with_index do |arg,i|
|
267
|
+
unless arg.kind_of?(Hash) and i == args.length-1
|
268
|
+
lcall_args.push(['',arg])
|
269
|
+
else
|
270
|
+
arg.each do |k,v|
|
271
|
+
lcall_args.push([k.to_s,v])
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
return lcall_args
|
277
|
+
|
278
|
+
end
|
279
|
+
|
280
|
+
#Sets the default conversion mode for RSRuby. The constants defined
|
281
|
+
#in #RSRuby should be used
|
282
|
+
def RSRuby.set_default_mode(m)
|
283
|
+
if m < -1 or m > TOP_CONVERSION
|
284
|
+
raise ArgumentError, "Invalid mode requested"
|
285
|
+
end
|
286
|
+
@@default_mode = m
|
287
|
+
end
|
288
|
+
#Returns the current default conversion mode as an Integer.
|
289
|
+
def RSRuby.get_default_mode
|
290
|
+
@@default_mode
|
291
|
+
end
|
292
|
+
|
293
|
+
#TODO - input/output setting methods don't work atm
|
294
|
+
def RSRuby.set_rsruby_input(m)
|
295
|
+
@@rsruby_input = m
|
296
|
+
end
|
297
|
+
def RSRuby.get_rsruby_input
|
298
|
+
@@rsruby_input
|
299
|
+
end
|
300
|
+
|
301
|
+
def RSRuby.set_rsruby_output(m)
|
302
|
+
@@rsruby_output = m
|
303
|
+
end
|
304
|
+
def RSRuby.get_rsruby_output
|
305
|
+
@@rsruby_output
|
306
|
+
end
|
307
|
+
|
308
|
+
def RSRuby.set_rsruby_showfiles(m)
|
309
|
+
@@rsruby_showfiles = m
|
310
|
+
end
|
311
|
+
def RSRuby.get_rsruby_showfiles
|
312
|
+
@@rsruby_showfiles
|
313
|
+
end
|
314
|
+
|
315
|
+
#Returns the current class table Hash for RSRuby.
|
316
|
+
def class_table
|
317
|
+
@@class_table
|
318
|
+
end
|
319
|
+
|
320
|
+
#Sets the RSRuby class table Hash.
|
321
|
+
def class_table=(h)
|
322
|
+
@@class_table = h
|
323
|
+
end
|
324
|
+
|
325
|
+
#Returns the current proc table Hash for RSRuby.
|
326
|
+
def proc_table
|
327
|
+
@@proc_table
|
328
|
+
end
|
329
|
+
|
330
|
+
#Sets the RSRuby proc table Hash.
|
331
|
+
def proc_table=(h)
|
332
|
+
@@proc_table = h
|
333
|
+
end
|
334
|
+
|
335
|
+
#Evaluates the given string in R. Returns the result of the evaluation.
|
336
|
+
def eval_R(s)
|
337
|
+
self.eval(self.parse(:text => s))
|
338
|
+
end
|
339
|
+
|
340
|
+
#Wraps the R help function.
|
341
|
+
def help(*args)
|
342
|
+
helpobj = @@cache['helpfun'].call(args)
|
343
|
+
self.print(helpobj)
|
344
|
+
end
|
345
|
+
|
346
|
+
:private
|
347
|
+
def __getitem__(name)
|
348
|
+
|
349
|
+
#Find the identifier and cache (unless already cached)
|
350
|
+
unless @@cache.has_key?(name)
|
351
|
+
@@cache[name] = @@cache['get'].lcall([['',name]])
|
352
|
+
end
|
353
|
+
|
354
|
+
#Retrieve object from cache
|
355
|
+
robj = @@cache[name]
|
356
|
+
|
357
|
+
return robj
|
358
|
+
|
359
|
+
end
|
360
|
+
|
361
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
#== Synopsis
|
2
|
+
#
|
3
|
+
#This is an extended #ERObj class inspired by the example given in the RPy
|
4
|
+
#manual used for R data frames.
|
5
|
+
#As with ERobj, methods caught by method_missing are converted into attribute
|
6
|
+
#calls on the R dataframe it represents. The rows and columns methods give
|
7
|
+
#access to the column and row names.
|
8
|
+
#
|
9
|
+
#== Usage
|
10
|
+
#
|
11
|
+
#See examples/dataframe.rb for examples of usage.
|
12
|
+
#
|
13
|
+
#--
|
14
|
+
#== Author
|
15
|
+
#Alex Gutteridge
|
16
|
+
#
|
17
|
+
#== Copyright
|
18
|
+
#Copyright (C) 2006 Alex Gutteridge
|
19
|
+
#
|
20
|
+
# The Original Code is the RPy python module.
|
21
|
+
#
|
22
|
+
# The Initial Developer of the Original Code is Walter Moreira.
|
23
|
+
# Portions created by the Initial Developer are Copyright (C) 2002
|
24
|
+
# the Initial Developer. All Rights Reserved.
|
25
|
+
#
|
26
|
+
# Contributor(s):
|
27
|
+
# Gregory R. Warnes <greg@warnes.net> (RPy Maintainer)
|
28
|
+
#
|
29
|
+
#This library is free software; you can redistribute it and/or
|
30
|
+
#modify it under the terms of the GNU Lesser General Public
|
31
|
+
#License as published by the Free Software Foundation; either
|
32
|
+
#version 2.1 of the License, or (at your option) any later version.
|
33
|
+
#
|
34
|
+
#This library is distributed in the hope that it will be useful,
|
35
|
+
#but WITHOUT ANY WARRANTY; without even the implied warranty of
|
36
|
+
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
37
|
+
#Lesser General Public License for more details.
|
38
|
+
#
|
39
|
+
#You should have received a copy of the GNU Lesser General Public
|
40
|
+
#License along with this library; if not, write to the Free Software
|
41
|
+
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
42
|
+
#++
|
43
|
+
|
44
|
+
require 'rsruby'
|
45
|
+
require 'rsruby/erobj'
|
46
|
+
|
47
|
+
class DataFrame < ERObj
|
48
|
+
|
49
|
+
#Returns an array of the row names used in the R data frame.
|
50
|
+
def rows
|
51
|
+
return @r.attr(@robj, 'row.names')
|
52
|
+
end
|
53
|
+
|
54
|
+
#Returns an array of the column names used in the R data frame.
|
55
|
+
def columns
|
56
|
+
cols = @r.colnames(@robj)
|
57
|
+
cols = [cols] unless cols.class == 'Array'
|
58
|
+
return cols
|
59
|
+
end
|
60
|
+
|
61
|
+
def method_missing(attr)
|
62
|
+
attr = attr.to_s
|
63
|
+
mode = RSRuby.get_default_mode
|
64
|
+
RSRuby.set_default_mode(RSRuby::BASIC_CONVERSION)
|
65
|
+
column_names = @r.colnames(@robj)
|
66
|
+
if attr == column_names or column_names.include?(attr)
|
67
|
+
RSRuby.set_default_mode(mode)
|
68
|
+
return @r['$'].call(@robj,attr.to_s)
|
69
|
+
end
|
70
|
+
|
71
|
+
#? Not sure what here...
|
72
|
+
RSRuby.set_default_mode(mode)
|
73
|
+
return super(attr)
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|