r_type 0.0.3
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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.travis.yml +14 -0
- data/Gemfile +3 -0
- data/Guardfile +9 -0
- data/LICENSE.txt +22 -0
- data/README.md +131 -0
- data/Rakefile +9 -0
- data/bin/r_console +17 -0
- data/lib/r_type.rb +41 -0
- data/lib/r_type/convert.rb +28 -0
- data/lib/r_type/core_ext.rb +30 -0
- data/lib/r_type/core_ext/boolean_delegate_r.rb +8 -0
- data/lib/r_type/core_ext/delegate_checker.rb +11 -0
- data/lib/r_type/core_ext/numeric_delegate_r.rb +20 -0
- data/lib/r_type/helper.rb +4 -0
- data/lib/r_type/helper/matrix_multiply.rb +13 -0
- data/lib/r_type/helper/robj_delegatable.rb +78 -0
- data/lib/r_type/helper/robj_delegatable_class_methods.rb +35 -0
- data/lib/r_type/helper/ruby_compareable.rb +9 -0
- data/lib/r_type/r.rb +50 -0
- data/lib/r_type/type/array.rb +7 -0
- data/lib/r_type/type/base.rb +14 -0
- data/lib/r_type/type/data_frame.rb +7 -0
- data/lib/r_type/type/function.rb +8 -0
- data/lib/r_type/type/integer.rb +7 -0
- data/lib/r_type/type/list.rb +7 -0
- data/lib/r_type/type/matrix.rb +65 -0
- data/lib/r_type/type/numeric.rb +7 -0
- data/lib/r_type/type/string.rb +7 -0
- data/lib/r_type/type/vector.rb +10 -0
- data/lib/r_type/version.rb +3 -0
- data/r_type.gemspec +28 -0
- data/sample/sample1.rb +34 -0
- data/sample/sample2.rb +38 -0
- data/sample/sample3.rb +79 -0
- data/sample/sample4.rb +43 -0
- data/sample/sample5.rb +61 -0
- data/spec/convert_spec.rb +93 -0
- data/spec/core_ext/boolean_delegate_r_spec.rb +39 -0
- data/spec/core_ext/numeric_delegate_r_spec.rb +27 -0
- data/spec/helper/robj_delegatable_spec.rb +68 -0
- data/spec/r_spec.rb +54 -0
- data/spec/spec_helper.rb +34 -0
- data/spec/type/base_spec.rb +52 -0
- data/spec/type/matrix_spec.rb +157 -0
- metadata +196 -0
data/sample/sample4.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require '../lib/r_type'
|
2
|
+
|
3
|
+
R.run do
|
4
|
+
a = matrix [0, 1, 2, 3, 4, 5, 6, 7, 9], ncol: 3
|
5
|
+
b = matrix [1, 0, -2]
|
6
|
+
|
7
|
+
print a
|
8
|
+
print b
|
9
|
+
print solve(a, b)
|
10
|
+
# x y z
|
11
|
+
# -----------------------
|
12
|
+
# [1,] | 0 3 6 = 1
|
13
|
+
# [2,] | 1 4 7 = 0
|
14
|
+
# [3,] | 2 5 9 = -2
|
15
|
+
#
|
16
|
+
# x = -2.333333
|
17
|
+
# y = 2.333333
|
18
|
+
# z = -1.000000
|
19
|
+
|
20
|
+
library("MASS")
|
21
|
+
c = matrix [1, 2, 3, 4, 5, 6, 7, 8, 9], ncol: 3
|
22
|
+
print ginv(c)
|
23
|
+
end
|
24
|
+
# >> [,1] [,2] [,3]
|
25
|
+
# >> [1,] 0 3 6
|
26
|
+
# >> [2,] 1 4 7
|
27
|
+
# >> [3,] 2 5 9
|
28
|
+
# >> [,1]
|
29
|
+
# >> [1,] 1
|
30
|
+
# >> [2,] 0
|
31
|
+
# >> [3,] -2
|
32
|
+
# >> [,1]
|
33
|
+
# >> [1,] -2.333333
|
34
|
+
# >> [2,] 2.333333
|
35
|
+
# >> [3,] -1.000000
|
36
|
+
# >> [,1] [,2] [,3]
|
37
|
+
# >> [1,] -0.3333333 -1 1
|
38
|
+
# >> [2,] -1.6666667 4 -2
|
39
|
+
# >> [3,] 1.0000000 -2 1
|
40
|
+
# >> [,1] [,2] [,3]
|
41
|
+
# >> [1,] -0.6388889 -5.555556e-02 0.5277778
|
42
|
+
# >> [2,] -0.1666667 -2.428613e-17 0.1666667
|
43
|
+
# >> [3,] 0.3055556 5.555556e-02 -0.1944444
|
data/sample/sample5.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require '../lib/r_type'
|
2
|
+
|
3
|
+
R.run do
|
4
|
+
a = matrix [3, 0, 0, 0, 4, 0, 0, 0, 1], ncol: 3
|
5
|
+
print eigen(a)
|
6
|
+
print svd(a)
|
7
|
+
|
8
|
+
b = matrix [0, 1, 2, 3, 4, 5, 6, 7, 9], ncol: 3
|
9
|
+
print eigen(b)
|
10
|
+
print qr(b)
|
11
|
+
end
|
12
|
+
# >> $values
|
13
|
+
# >> [1] 4 3 1
|
14
|
+
# >>
|
15
|
+
# >> $vectors
|
16
|
+
# >> [,1] [,2] [,3]
|
17
|
+
# >> [1,] 0 1 0
|
18
|
+
# >> [2,] 1 0 0
|
19
|
+
# >> [3,] 0 0 1
|
20
|
+
# >>
|
21
|
+
# >> $d
|
22
|
+
# >> [1] 4 3 1
|
23
|
+
# >>
|
24
|
+
# >> $u
|
25
|
+
# >> [,1] [,2] [,3]
|
26
|
+
# >> [1,] 0 1 0
|
27
|
+
# >> [2,] 1 0 0
|
28
|
+
# >> [3,] 0 0 1
|
29
|
+
# >>
|
30
|
+
# >> $v
|
31
|
+
# >> [,1] [,2] [,3]
|
32
|
+
# >> [1,] 0 1 0
|
33
|
+
# >> [2,] 1 0 0
|
34
|
+
# >> [3,] 0 0 1
|
35
|
+
# >>
|
36
|
+
# >> $values
|
37
|
+
# >> [1] 13.985686 -1.169156 0.183470
|
38
|
+
# >>
|
39
|
+
# >> $vectors
|
40
|
+
# >> [,1] [,2] [,3]
|
41
|
+
# >> [1,] -0.4263524 -0.9366202 0.2264150
|
42
|
+
# >> [2,] -0.5474684 -0.2042614 -0.8684128
|
43
|
+
# >> [3,] -0.7200708 0.2846399 0.4411298
|
44
|
+
# >>
|
45
|
+
# >> $qr
|
46
|
+
# >> [,1] [,2] [,3]
|
47
|
+
# >> [1,] -2.2360680 -6.2609903 -11.1803399
|
48
|
+
# >> [2,] 0.4472136 3.2863353 6.3900965
|
49
|
+
# >> [3,] 0.8944272 0.9990708 0.4082483
|
50
|
+
# >>
|
51
|
+
# >> $rank
|
52
|
+
# >> [1] 3
|
53
|
+
# >>
|
54
|
+
# >> $qraux
|
55
|
+
# >> [1] 1.0000000 1.0430999 0.4082483
|
56
|
+
# >>
|
57
|
+
# >> $pivot
|
58
|
+
# >> [1] 1 2 3
|
59
|
+
# >>
|
60
|
+
# >> attr(,"class")
|
61
|
+
# >> [1] "qr"
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RType::Convert do
|
4
|
+
let!(:rsruby) { rsruby_stub }
|
5
|
+
let(:converter) { RType::Convert.new }
|
6
|
+
|
7
|
+
def robj original_value
|
8
|
+
rsruby_obj = double("rsruby::robj (#{original_value})")
|
9
|
+
rsruby_obj.stub(:to_ruby).and_return original_value
|
10
|
+
rsruby_obj
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#convert' do
|
14
|
+
let(:converted_value) { value }
|
15
|
+
let(:length_val) { 0 }
|
16
|
+
|
17
|
+
shared_examples_for 'convert RObj to' do |klass|
|
18
|
+
before do
|
19
|
+
rsruby.stub(:[]).with(:length).and_return double(call: length_val)
|
20
|
+
rsruby.stub(:[]).with(:class).and_return double(call: r_class)
|
21
|
+
rsruby.stub(:[]).with(:mode).and_return 'numeric'
|
22
|
+
@robj = robj(value)
|
23
|
+
::RObj.stub(:===).with(@robj).and_return true
|
24
|
+
end
|
25
|
+
|
26
|
+
subject { converter.convert @robj }
|
27
|
+
it { should be_a klass }
|
28
|
+
it { should == converted_value }
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'DataFrame' do
|
32
|
+
let(:value) { { x: [1,2,3] } }
|
33
|
+
let(:r_class) { 'data.frame' }
|
34
|
+
it_behaves_like 'convert RObj to', RType::DataFrame
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'Function' do
|
38
|
+
let(:value) { 'R-function' }
|
39
|
+
let(:r_class) { 'function' }
|
40
|
+
it_behaves_like 'convert RObj to', RType::Function
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'List' do
|
44
|
+
let(:value) { [1, 2, 3] }
|
45
|
+
let(:r_class) { 'list' }
|
46
|
+
it_behaves_like 'convert RObj to', RType::List
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'Array' do
|
50
|
+
let(:value) { [1, 2, 3] }
|
51
|
+
let(:r_class) { 'array' }
|
52
|
+
it_behaves_like 'convert RObj to', RType::Array
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'Matrix' do
|
56
|
+
let(:value) { [[1, 2], [3, 4]] }
|
57
|
+
let(:r_class) { 'matrix' }
|
58
|
+
let(:converted_value) { ::Matrix.rows value }
|
59
|
+
it_behaves_like 'convert RObj to', RType::Matrix
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'Vector' do
|
63
|
+
let(:length_val) { 2 }
|
64
|
+
let(:value) { [1, 2, 3] }
|
65
|
+
let(:r_class) { 'numeric' }
|
66
|
+
it_behaves_like 'convert RObj to', RType::Vector
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'String' do
|
70
|
+
let(:value) { "hello world" }
|
71
|
+
let(:r_class) { 'character' }
|
72
|
+
it_behaves_like 'convert RObj to', RType::String
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'Numeric' do
|
76
|
+
let(:value) { 99.0 }
|
77
|
+
let(:r_class) { 'numeric' }
|
78
|
+
it_behaves_like 'convert RObj to', RType::Numeric
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'Integer' do
|
82
|
+
let(:value) { 31 }
|
83
|
+
let(:r_class) { 'integer' }
|
84
|
+
it_behaves_like 'convert RObj to', RType::Integer
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'Base' do
|
88
|
+
let(:value) { 100 }
|
89
|
+
let(:r_class) { 'unknown' }
|
90
|
+
it_behaves_like 'convert RObj to', RType::Base
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RType::CoreExt::BooleanDelegateR do
|
4
|
+
let(:num) { 3 }
|
5
|
+
let(:matrix) { RType::Matrix[[1, 3], [2, 4]] }
|
6
|
+
|
7
|
+
describe '<' do
|
8
|
+
subject { num < matrix }
|
9
|
+
|
10
|
+
it 'Matrix[[false, false], [false, true]]' do
|
11
|
+
subject[1, 1].should be_false
|
12
|
+
subject[1, 2].should be_false
|
13
|
+
subject[2, 1].should be_false
|
14
|
+
subject[2, 2].should be_true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '>' do
|
19
|
+
subject { num > matrix }
|
20
|
+
|
21
|
+
it 'Matrix[[true, false], [true, false]]' do
|
22
|
+
subject[1, 1].should be_true
|
23
|
+
subject[1, 2].should be_false
|
24
|
+
subject[2, 1].should be_true
|
25
|
+
subject[2, 2].should be_false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '=~' do
|
30
|
+
subject { num =~ matrix }
|
31
|
+
|
32
|
+
it 'Matrix[[false, true], [false, false]]' do
|
33
|
+
subject[1, 1].should be_false
|
34
|
+
subject[1, 2].should be_true
|
35
|
+
subject[2, 1].should be_false
|
36
|
+
subject[2, 2].should be_false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RType::CoreExt::NumericDelegateR do
|
4
|
+
let(:num) { 100 }
|
5
|
+
let(:matrix) { RType::Matrix[[1, 3], [2, 4]] }
|
6
|
+
|
7
|
+
describe '+' do
|
8
|
+
subject { num + matrix }
|
9
|
+
it { should == RType::Matrix[[101, 103], [102, 104]] }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '-' do
|
13
|
+
subject { num - matrix }
|
14
|
+
it { should == RType::Matrix[[99, 97], [98, 96]] }
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '/' do
|
18
|
+
let(:num) { 12 }
|
19
|
+
subject { num / matrix }
|
20
|
+
it { should == RType::Matrix[[12.0, 4.0], [6.0, 3.0]] }
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '*' do
|
24
|
+
subject { num * matrix }
|
25
|
+
it { should == RType::Matrix[[100, 300], [200, 400]] }
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RType::Helper::RObjDelegatable do
|
4
|
+
let(:klass) do
|
5
|
+
Class.new(Delegator) do
|
6
|
+
include RType::Helper::RObjDelegatable
|
7
|
+
|
8
|
+
def initialize robj=nil, ruby_obj=nil
|
9
|
+
if robj
|
10
|
+
@robj = robj
|
11
|
+
else
|
12
|
+
@ruby_obj = ruby_obj
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
let(:ruby_obj) { double("ruby_obj") }
|
18
|
+
let(:robj) { double("robj") }
|
19
|
+
let(:r_stub) { double("R") }
|
20
|
+
|
21
|
+
before do
|
22
|
+
robj.stub(:to_ruby).with(RSRuby::BASIC_CONVERSION).and_return ruby_obj
|
23
|
+
robj.stub(:as_r).and_return robj
|
24
|
+
ruby_obj.stub_chain(:as_r, :robj).and_return robj
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'has R-obj' do
|
28
|
+
subject { klass.new robj, nil }
|
29
|
+
|
30
|
+
its(:ruby_obj) { should == ruby_obj }
|
31
|
+
its(:robj) { should == robj }
|
32
|
+
its(:as_r) { should == robj }
|
33
|
+
its(:to_ruby) { should == ruby_obj }
|
34
|
+
its(:inspect) { should =~ /RType::.*robj/ }
|
35
|
+
|
36
|
+
it 'delegate a method to R' do
|
37
|
+
R.stub(:[]).with('+') { r_stub }
|
38
|
+
r_stub.stub(:call).with(subject, 100).and_return 150
|
39
|
+
expect(subject + 100).to be_eql 150
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'delegate a method to Ruby' do
|
43
|
+
ruby_obj.should_receive(:hoge).and_return 'Hello world'
|
44
|
+
expect(subject.hoge).to be_eql 'Hello world'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'has Ruby-obj' do
|
49
|
+
subject { klass.new nil, ruby_obj }
|
50
|
+
|
51
|
+
its(:ruby_obj) { should == ruby_obj }
|
52
|
+
its(:robj) { should == robj }
|
53
|
+
its(:as_r) { should == robj }
|
54
|
+
its(:to_ruby) { should == ruby_obj }
|
55
|
+
its(:inspect) { should =~ /RType::.*ruby_obj/ }
|
56
|
+
|
57
|
+
it 'delegate a method to R' do
|
58
|
+
R.stub(:[]).with('+') { r_stub }
|
59
|
+
r_stub.stub(:call).with(subject, 100).and_return 150
|
60
|
+
expect(subject + 100).to be_eql 150
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'delegate a method to Ruby' do
|
64
|
+
ruby_obj.should_receive(:hoge).and_return 'Hello world'
|
65
|
+
expect(subject.hoge).to be_eql 'Hello world'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/spec/r_spec.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RType::R do
|
4
|
+
describe '#lazy_expression' do
|
5
|
+
before { @exp = RType::R.lazy_expression('function(x) x * 10') }
|
6
|
+
|
7
|
+
it 'should be a R function' do
|
8
|
+
@exp.call(3.0).to_ruby.should == 30
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#method_missing' do
|
13
|
+
context 'call a RSRuby method' do
|
14
|
+
subject { RType::R.eval_R '11 + 44' }
|
15
|
+
it { should == 55 }
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'call a R-function' do
|
19
|
+
subject { RType::R.sum 11, 22 }
|
20
|
+
it { should == 33 }
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'assign a value to R-variable' do
|
24
|
+
before { RType::R.x = 100 }
|
25
|
+
subject { RType::R.x }
|
26
|
+
it { should == 100 }
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'get a R-variable' do
|
30
|
+
before { RType::R.eval_R 'y = 900' }
|
31
|
+
subject { RType::R.y }
|
32
|
+
it { should == 900 }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe ::R do
|
38
|
+
it { should == RType::R }
|
39
|
+
|
40
|
+
describe 'R::Matrix' do
|
41
|
+
subject { ::R::Matrix }
|
42
|
+
it { should == ::RType::Matrix }
|
43
|
+
end
|
44
|
+
|
45
|
+
describe 'R::List' do
|
46
|
+
subject { ::R::List }
|
47
|
+
it { should == ::RType::List }
|
48
|
+
end
|
49
|
+
|
50
|
+
describe 'R::Vector' do
|
51
|
+
subject { ::R::Vector }
|
52
|
+
it { should == ::RType::Vector }
|
53
|
+
end
|
54
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.expand_path('../../lib/r_type', __FILE__)
|
2
|
+
|
3
|
+
module RType::SpecDSL
|
4
|
+
def rsruby_stub
|
5
|
+
rsruby = double("rsruby")
|
6
|
+
RType::R.stub(:rsruby).and_return(rsruby)
|
7
|
+
proc_table = {}
|
8
|
+
rsruby.stub(:default_mode=).with(4)
|
9
|
+
rsruby.stub(:proc_table) { proc_table }
|
10
|
+
rsruby
|
11
|
+
end
|
12
|
+
|
13
|
+
def rsruby_func_stub rsruby, name, args, response
|
14
|
+
func = double(name.to_s)
|
15
|
+
func.stub(:call).with(*args).and_return response
|
16
|
+
func.stub(:is_function?).and_return true
|
17
|
+
rsruby.stub(:[]).with(name).and_return func
|
18
|
+
func
|
19
|
+
end
|
20
|
+
|
21
|
+
def rsruby_variable_stub rsruby, name, value
|
22
|
+
variable = RType::Base.new double(name.to_s)
|
23
|
+
variable.stub(:to_ruby).and_return value
|
24
|
+
variable.stub(:is_function?).and_return false
|
25
|
+
rsruby_func_stub rsruby, :assign, [name.to_s, value], variable
|
26
|
+
rsruby.stub(:[]).with(name).and_return variable
|
27
|
+
variable
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
RSpec.configure do |config|
|
32
|
+
config.mock_framework = :rspec
|
33
|
+
config.include RType::SpecDSL
|
34
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RType::Base do
|
4
|
+
context 'c(1,2,3)' do
|
5
|
+
subject { R.eval_R("c(1,2,3)") }
|
6
|
+
|
7
|
+
it { should be_include 3 }
|
8
|
+
it { should == [1.0, 2.0, 3.0] }
|
9
|
+
|
10
|
+
its(:to_ruby) { should == [1.0, 2.0, 3.0] }
|
11
|
+
its('to_ruby.inspect') { should == '[1.0, 2.0, 3.0]' }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'auto conversion' do
|
15
|
+
describe 'R-object receive a method' do
|
16
|
+
subject { R.eval_R("c(5,6)") }
|
17
|
+
it { should == [5,6] }
|
18
|
+
it { should be_include 5 }
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'Ruby-object receive a method with R-object' do
|
22
|
+
subject { [5,6].include? R.eval_R("6") }
|
23
|
+
it { should be_true }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#method_missing' do
|
28
|
+
context 'c(1,2,3)' do
|
29
|
+
let(:obj) { R.eval_R("c(1,2,3)") }
|
30
|
+
|
31
|
+
describe '+ 100' do
|
32
|
+
subject { obj + 100 }
|
33
|
+
it { should == [101, 102, 103] }
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '- 100' do
|
37
|
+
subject { obj - 100 }
|
38
|
+
it { should == [-99, -98, -97] }
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '* 100' do
|
42
|
+
subject { obj * 100 }
|
43
|
+
it { should == [100, 200, 300] }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'call a Ruby-method' do
|
48
|
+
subject { R.eval_R("999") }
|
49
|
+
its(:to_s) { should == '999.0' }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|