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.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.travis.yml +14 -0
  4. data/Gemfile +3 -0
  5. data/Guardfile +9 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +131 -0
  8. data/Rakefile +9 -0
  9. data/bin/r_console +17 -0
  10. data/lib/r_type.rb +41 -0
  11. data/lib/r_type/convert.rb +28 -0
  12. data/lib/r_type/core_ext.rb +30 -0
  13. data/lib/r_type/core_ext/boolean_delegate_r.rb +8 -0
  14. data/lib/r_type/core_ext/delegate_checker.rb +11 -0
  15. data/lib/r_type/core_ext/numeric_delegate_r.rb +20 -0
  16. data/lib/r_type/helper.rb +4 -0
  17. data/lib/r_type/helper/matrix_multiply.rb +13 -0
  18. data/lib/r_type/helper/robj_delegatable.rb +78 -0
  19. data/lib/r_type/helper/robj_delegatable_class_methods.rb +35 -0
  20. data/lib/r_type/helper/ruby_compareable.rb +9 -0
  21. data/lib/r_type/r.rb +50 -0
  22. data/lib/r_type/type/array.rb +7 -0
  23. data/lib/r_type/type/base.rb +14 -0
  24. data/lib/r_type/type/data_frame.rb +7 -0
  25. data/lib/r_type/type/function.rb +8 -0
  26. data/lib/r_type/type/integer.rb +7 -0
  27. data/lib/r_type/type/list.rb +7 -0
  28. data/lib/r_type/type/matrix.rb +65 -0
  29. data/lib/r_type/type/numeric.rb +7 -0
  30. data/lib/r_type/type/string.rb +7 -0
  31. data/lib/r_type/type/vector.rb +10 -0
  32. data/lib/r_type/version.rb +3 -0
  33. data/r_type.gemspec +28 -0
  34. data/sample/sample1.rb +34 -0
  35. data/sample/sample2.rb +38 -0
  36. data/sample/sample3.rb +79 -0
  37. data/sample/sample4.rb +43 -0
  38. data/sample/sample5.rb +61 -0
  39. data/spec/convert_spec.rb +93 -0
  40. data/spec/core_ext/boolean_delegate_r_spec.rb +39 -0
  41. data/spec/core_ext/numeric_delegate_r_spec.rb +27 -0
  42. data/spec/helper/robj_delegatable_spec.rb +68 -0
  43. data/spec/r_spec.rb +54 -0
  44. data/spec/spec_helper.rb +34 -0
  45. data/spec/type/base_spec.rb +52 -0
  46. data/spec/type/matrix_spec.rb +157 -0
  47. 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
@@ -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