RSRuby 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +102 -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/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 +87 -0
data/test/tc_robj.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'rsruby'
|
3
|
+
|
4
|
+
unless $r
|
5
|
+
$r = RSRuby.instance
|
6
|
+
end
|
7
|
+
|
8
|
+
class TestRObj < Test::Unit::TestCase
|
9
|
+
|
10
|
+
def setup
|
11
|
+
RSRuby.set_default_mode(RSRuby::NO_DEFAULT)
|
12
|
+
$r.class_table.clear
|
13
|
+
$r.proc_table.clear
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_type
|
17
|
+
assert_equal($r.array.class, RObj)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_call
|
21
|
+
#TODO
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_keyword_parameters
|
25
|
+
#TODO - In RPy keyword parameters are converted like the method calls
|
26
|
+
#In ruby this isn't such a problem because you can use quoted strings
|
27
|
+
#but we will implement it anyway.
|
28
|
+
$r.list.autoconvert(RSRuby::BASIC_CONVERSION)
|
29
|
+
d = $r.list(:foo => 'foo', :bar_foo => 'bar.foo', :print_ => 'print', :as_data_frame => 'as.data.frame')
|
30
|
+
d.each do |k,v|
|
31
|
+
assert_equal(k, d[k])
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_bad_keyword_parameters
|
36
|
+
#TODO?
|
37
|
+
#assert_raises(ArgumentError){$r.list(:none => 1)}
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_name_conversions
|
41
|
+
assert_equal($r.array, $r['array'])
|
42
|
+
assert_equal($r.print_,$r['print'])
|
43
|
+
assert_equal($r.as_data_frame, $r['as.data.frame'])
|
44
|
+
assert_equal($r.attr__, $r['attr<-'])
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_not_found
|
48
|
+
assert_raises(RException){$r.foo}
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_name_length_one
|
52
|
+
assert_nothing_raised{$r.T}
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_autoconvert
|
56
|
+
$r.seq.autoconvert(RSRuby::BASIC_CONVERSION)
|
57
|
+
assert_equal($r.seq(10), (1..10).to_a)
|
58
|
+
$r.seq.autoconvert(RSRuby::NO_CONVERSION)
|
59
|
+
assert_equal($r.seq(10).class, RObj)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_bad_autoconvert
|
63
|
+
assert_raises(ArgumentError){$r.seq.autoconvert(RSRuby::TOP_CONVERSION+1)}
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_get_autoconvert
|
67
|
+
$r.seq.autoconvert(RSRuby::BASIC_CONVERSION)
|
68
|
+
mode = $r.seq.autoconvert
|
69
|
+
assert_equal(mode, RSRuby::BASIC_CONVERSION)
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_r_gc
|
73
|
+
#TODO - How can this work?
|
74
|
+
$r.seq.autoconvert(RSRuby::NO_CONVERSION)
|
75
|
+
arr = $r.seq(100000)
|
76
|
+
$r.gc
|
77
|
+
assert($r['['].call(arr,10))
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_lcall
|
81
|
+
RSRuby.set_default_mode(RSRuby::NO_CONVERSION)
|
82
|
+
arr = $r.c.lcall([['',0],['a',1],['b',2],['c',3]])
|
83
|
+
RSRuby.set_default_mode(RSRuby::BASIC_CONVERSION)
|
84
|
+
assert_equal($r.names(arr), ['','a','b','c'])
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
data/test/tc_sigint.rb
ADDED
data/test/tc_to_r.rb
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'rsruby'
|
3
|
+
|
4
|
+
unless $r
|
5
|
+
$r = RSRuby.instance
|
6
|
+
end
|
7
|
+
|
8
|
+
class Foo
|
9
|
+
end
|
10
|
+
|
11
|
+
class Bar
|
12
|
+
def initialize(x)
|
13
|
+
@x = x
|
14
|
+
end
|
15
|
+
def as_r
|
16
|
+
@x
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class TestToR < Test::Unit::TestCase
|
21
|
+
|
22
|
+
def setup
|
23
|
+
RSRuby.set_default_mode(RSRuby::NO_DEFAULT)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_robj_to_r
|
27
|
+
|
28
|
+
$r.c.autoconvert(RSRuby::NO_CONVERSION)
|
29
|
+
|
30
|
+
r1 = $r.c(4)
|
31
|
+
r2 = $r.c('foo')
|
32
|
+
r3 = $r.c(['a','b'])
|
33
|
+
|
34
|
+
assert($r['=='].call(r1,4))
|
35
|
+
assert($r['=='].call(r2,'foo'))
|
36
|
+
assert($r['=='].call(r3,['a','b']))
|
37
|
+
|
38
|
+
assert_equal($r.typeof($r.eval),'closure')
|
39
|
+
assert_equal($r.typeof($r.eval($r.eval)), 'closure')
|
40
|
+
assert_equal($r.typeof($r.eval([$r.eval,$r.eval])), 'list')
|
41
|
+
|
42
|
+
#Same tests as above in basic mode - should be identical
|
43
|
+
$r.c.autoconvert(RSRuby::BASIC_CONVERSION)
|
44
|
+
|
45
|
+
r1 = $r.c(4)
|
46
|
+
r2 = $r.c('foo')
|
47
|
+
r3 = $r.c(['a','b'])
|
48
|
+
|
49
|
+
assert($r['=='].call(r1,4))
|
50
|
+
assert($r['=='].call(r2,'foo'))
|
51
|
+
assert($r['=='].call(r3,['a','b']))
|
52
|
+
|
53
|
+
assert_equal($r.typeof($r.eval),'closure')
|
54
|
+
assert_equal($r.typeof($r.eval($r.eval)), 'closure')
|
55
|
+
assert_equal($r.typeof($r.eval([$r.eval,$r.eval])), 'list')
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_empty_array_to_null
|
60
|
+
assert($r.is_null([]))
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_boolean_to_logical
|
64
|
+
assert_equal($r.c(true),true)
|
65
|
+
assert_equal($r.c(true).class,true.class)
|
66
|
+
assert_equal($r.c(false),false)
|
67
|
+
assert_equal($r.c(false).class,false.class)
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_int_to_int
|
71
|
+
$r.c.autoconvert(RSRuby::NO_CONVERSION)
|
72
|
+
assert_equal($r.typeof($r.c(4)), 'integer')
|
73
|
+
$r.c.autoconvert(RSRuby::BASIC_CONVERSION)
|
74
|
+
assert_equal($r.typeof($r.c(4)), 'integer')
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_float_to_float
|
78
|
+
$r.c.autoconvert(RSRuby::NO_CONVERSION)
|
79
|
+
assert_equal($r.typeof($r.c(4.5)), 'double')
|
80
|
+
$r.c.autoconvert(RSRuby::BASIC_CONVERSION)
|
81
|
+
assert_equal($r.typeof($r.c(4.5)), 'double')
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_char_to_char
|
85
|
+
$r.c.autoconvert(RSRuby::NO_CONVERSION)
|
86
|
+
assert_equal($r.typeof($r.c('foo')), 'character')
|
87
|
+
$r.c.autoconvert(RSRuby::BASIC_CONVERSION)
|
88
|
+
assert_equal($r.typeof($r.c('foo')), 'character')
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_hash_to_named_vector
|
92
|
+
$r.c.autoconvert(RSRuby::NO_CONVERSION)
|
93
|
+
assert_equal($r.typeof($r.c(:foo => 5, :bar => 7)),'integer')
|
94
|
+
assert($r.attributes($r.c(:foo => 5, :bar => 7))['names'].include?('foo'))
|
95
|
+
assert($r.attributes($r.c(:foo => 5, :bar => 7))['names'].include?('bar'))
|
96
|
+
#TODO - these fail because of the different calling semantics in
|
97
|
+
#RSRuby
|
98
|
+
#$r.c.autoconvert(RSRuby::BASIC_CONVERSION)
|
99
|
+
#assert_equal($r.typeof($r.c(:foo => 5, :bar => 7)),'integer')
|
100
|
+
#assert($r.attributes($r.c(:foo => 5, :bar => 7))['names'].include?('foo'))
|
101
|
+
#assert($r.attributes($r.c(:foo => 5, :bar => 7))['names'].include?('bar'))
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_array_to_vector
|
105
|
+
$r.c.autoconvert(RSRuby::NO_CONVERSION)
|
106
|
+
assert_equal($r.length($r.c(1,2,3,4)),4)
|
107
|
+
$r.c.autoconvert(RSRuby::BASIC_CONVERSION)
|
108
|
+
assert_equal($r.length($r.c(1,2,3,4)),4)
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_not_convertible
|
112
|
+
#TODO - range?
|
113
|
+
assert_raises(ArgumentError){$r.c(1..10)}
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_instances_not_convertible
|
117
|
+
foo = Foo.new
|
118
|
+
assert_raises(ArgumentError){$r.c(foo)}
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_as_r_method
|
122
|
+
$r.c.autoconvert(RSRuby::BASIC_CONVERSION)
|
123
|
+
|
124
|
+
a = Bar.new(3)
|
125
|
+
b = Bar.new('foo')
|
126
|
+
d = Bar.new($r.seq)
|
127
|
+
|
128
|
+
assert_equal($r.c(a),3)
|
129
|
+
assert_equal($r.c(b),'foo')
|
130
|
+
assert_equal($r.c(d).call(1,3),[1,2,3])
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_max_int_to_r
|
135
|
+
#TODO
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_inf_to_r
|
139
|
+
#TODO
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_NaN_to_r
|
143
|
+
#TODO
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
data/test/tc_to_ruby.rb
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'rsruby'
|
3
|
+
|
4
|
+
unless $r
|
5
|
+
$r = RSRuby.instance
|
6
|
+
end
|
7
|
+
|
8
|
+
class TestToRuby < Test::Unit::TestCase
|
9
|
+
|
10
|
+
def setup
|
11
|
+
RSRuby.set_default_mode(RSRuby::NO_DEFAULT)
|
12
|
+
$r.seq.autoconvert(RSRuby::BASIC_CONVERSION)
|
13
|
+
$r.c.autoconvert(RSRuby::BASIC_CONVERSION)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_null_to_nil
|
17
|
+
assert($r.attributes($r.seq).nil?)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_factor_to_list
|
21
|
+
assert_equal($r.factor([1,2,3,4]), ['1','2','3','4'])
|
22
|
+
assert_equal($r.factor([1,1,1,2]), ['1','1','1','2'])
|
23
|
+
assert_equal($r.factor(['a','b','c']), ['a','b','c'])
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_NA_int
|
27
|
+
#The formula on right should equal smallest Fixnum
|
28
|
+
#in current Ruby build (can vary)
|
29
|
+
assert_equal($r.NA, (-1)*(2**((1.size*8)-1)))
|
30
|
+
assert($r.is_na($r.NA))
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_NA_string
|
34
|
+
assert_equal($r.eval_R('as.character(NA)'), 'NA')
|
35
|
+
assert_equal($r.as_character($r.NA), 'NA')
|
36
|
+
assert_equal($r.as_character($r.NaN), 'NaN')
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_factor_NA
|
40
|
+
assert_equal($r.factor($r.NA) , 'NA')
|
41
|
+
assert_equal($r.factor($r.NaN), 'NaN')
|
42
|
+
assert_equal($r.factor($r.as_character('NA')), 'NA')
|
43
|
+
|
44
|
+
xi = [1,2,$r.NA,$r.NaN,4]
|
45
|
+
assert_equal($r.factor(xi), ['1','2','NA','NaN','4'])
|
46
|
+
|
47
|
+
xd = [1.01,2.02,$r.NA,$r.NaN,4.04]
|
48
|
+
assert_equal($r.factor(xd), ['1.01','2.02','NA','NaN','4.04'])
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_NA_list
|
53
|
+
|
54
|
+
#TODO - RPy has commented out these tests as well.
|
55
|
+
#The conversion between NA/NaN and Ruby seems a little confused
|
56
|
+
#at the moment
|
57
|
+
|
58
|
+
xi = [1,2,$r.NA,$r.NaN,4]
|
59
|
+
assert_equal($r.as_character(xi), ['1','2','NA','NaN','4'])
|
60
|
+
#assert_equal($r.as_numeric(xi) , [1.0,2.0,$r.NA,$r.NaN,4.0])
|
61
|
+
#assert_equal($r.as_integer(xi) , [1,2,$r.NA,$r.NaN,4])
|
62
|
+
assert_equal($r.factor(xi) , ['1','2','NA','NaN','4'])
|
63
|
+
assert_equal($r.is_na(xi) , [false, false, true, true, false])
|
64
|
+
|
65
|
+
xd = [1.01,2.02,$r.NA,$r.NaN,4.04]
|
66
|
+
assert_equal($r.as_character(xd), ['1.01','2.02','NA','NaN','4.04'])
|
67
|
+
#assert_equal($r.as_numeric(xi) , [1.01,2.01,$r.NA,$r.NaN,4.01])
|
68
|
+
assert_equal($r.as_integer(xd) , [1,2,$r.NA,$r.NA,4])
|
69
|
+
assert_equal($r.factor(xd) , ['1.01','2.02','NA','NaN','4.04'])
|
70
|
+
assert_equal($r.is_na(xd) , [false, false, true, true, false])
|
71
|
+
end
|
72
|
+
|
73
|
+
#TODO - table.txt?????????
|
74
|
+
def test_dataframe_to_list
|
75
|
+
$r.read_table.autoconvert(RSRuby::BASIC_CONVERSION)
|
76
|
+
assert_equal($r.read_table('test/table.txt', {:header => 1}),
|
77
|
+
{
|
78
|
+
'A' => ['X1','X2','X3'],
|
79
|
+
'C' => [5,8,2],
|
80
|
+
'B' => [4.0,7.0,6.0],
|
81
|
+
'D' => ['6','9','Foo']
|
82
|
+
})
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_logical_to_boolean
|
86
|
+
assert_equal($r.TRUE, true)
|
87
|
+
assert_equal($r.T, true)
|
88
|
+
assert_equal($r.FALSE, false)
|
89
|
+
assert_equal($r.F, false)
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_int_to_int
|
93
|
+
assert_equal($r.as_integer(5),5)
|
94
|
+
assert_equal($r.as_integer(-3),-3)
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_float_to_float
|
98
|
+
assert_equal($r.as_real(5),5.0)
|
99
|
+
assert_equal($r.as_real(3.1),3.1)
|
100
|
+
assert_equal($r.as_real(-3.1), -3.1)
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_complex_to_complex
|
104
|
+
#TODO - Think about Complex support
|
105
|
+
assert_equal($r.as_complex(Complex(1,2)), Complex(1,2))
|
106
|
+
assert_equal($r.as_complex(Complex(1.5,-3.4)), Complex(1.5,-3.4))
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_str_to_str
|
110
|
+
$r.as_data_frame.autoconvert(RSRuby::NO_CONVERSION)
|
111
|
+
assert_equal($r.class_($r.as_data_frame([1,2,3])), 'data.frame')
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_vector_length_one
|
115
|
+
assert_equal($r.c(1),1)
|
116
|
+
assert_equal($r.c('foo'),'foo')
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_int_vector_to_array
|
120
|
+
assert_equal($r.seq(10),[1,2,3,4,5,6,7,8,9,10])
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_float_vector_to_array
|
124
|
+
assert_equal($r.seq(1,2,{:by => 0.5}), [1.0,1.5,2.0])
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_complex_vector_to_array
|
128
|
+
assert_equal($r.c(Complex(1,2),Complex(2,-3)),[Complex(1,2),Complex(2,-3)])
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_str_vector_to_array
|
132
|
+
assert_equal($r.c('Foo','Bar'),['Foo','Bar'])
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_list_to_array
|
136
|
+
$r.list.autoconvert(RSRuby::BASIC_CONVERSION)
|
137
|
+
assert_equal($r.list(1,2.0,'foo'),[1,2.0,'foo'])
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_named_vector_to_hash
|
141
|
+
$r.c.autoconvert(RSRuby::NO_CONVERSION)
|
142
|
+
a = $r.attr__($r.c(1,2,3), 'names', ['foo','bar','baz'])
|
143
|
+
assert_equal(a,{'foo'=>1,'bar'=>2,'baz'=>3})
|
144
|
+
assert_equal($r.list(:foo => 1, :bar => 2, :baz => 3),{'foo'=>1,'bar'=>2,'baz'=>3})
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_vector_coercion
|
148
|
+
$r.c.autoconvert(RSRuby::NO_CONVERSION)
|
149
|
+
assert_equal($r.typeof($r.c(1,2,3)), 'integer')
|
150
|
+
assert_equal($r.typeof($r.c(1,2.0,3)), 'double')
|
151
|
+
assert_equal($r.typeof($r.c(1,Complex(2,3),3)), 'complex')
|
152
|
+
assert_equal($r.typeof($r.c(1,'foo',3)), 'character')
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
data/test/tc_util.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'rsruby'
|
3
|
+
|
4
|
+
class TestUtil < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_as_list
|
7
|
+
#TODO
|
8
|
+
#assert_equal($r.as_lis
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_with_mode
|
12
|
+
#TODO
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_r_code
|
16
|
+
#TODO - Not sure about this. I use r.eval_R('')
|
17
|
+
#Not really a util
|
18
|
+
end
|
19
|
+
end
|
data/test/tc_vars.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'rsruby'
|
3
|
+
|
4
|
+
unless $r
|
5
|
+
$r = RSRuby.instance
|
6
|
+
end
|
7
|
+
|
8
|
+
class TestVars < Test::Unit::TestCase
|
9
|
+
|
10
|
+
def test_get_vars
|
11
|
+
$r.eval_R("f<-function(x) x+1")
|
12
|
+
$r.assign('x',100)
|
13
|
+
$r.assign('v',(1..10).to_a)
|
14
|
+
#There is a difference here between RPy and us
|
15
|
+
#a final hash argument is treated as named arguments
|
16
|
+
#to the original function call (assign) not as a list
|
17
|
+
#to be given to the function
|
18
|
+
$r.c.autoconvert(RSRuby::NO_CONVERSION)
|
19
|
+
$r.assign('d',$r.c({'a' => 1, 'b' => 2}))
|
20
|
+
$r.c.autoconvert(RSRuby::BASIC_CONVERSION)
|
21
|
+
|
22
|
+
assert_equal($r.x, 100)
|
23
|
+
assert_equal($r.v, (1..10).to_a)
|
24
|
+
assert_equal($r.d, $r.c({'a' => 1, 'b' => 2}))
|
25
|
+
assert_equal($r.f.class, $r.c.class)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|