rserve-client 0.2.0 → 0.2.1
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.tar.gz.sig +1 -1
- data/History.txt +4 -0
- data/README.txt +12 -12
- data/lib/rserve.rb +1 -1
- data/lib/rserve/rexp.rb +11 -6
- data/lib/rserve/rexp/wrapper.rb +36 -19
- data/spec/rserve_connection_spec.rb +12 -2
- data/spec/rserve_rexp_to_ruby_spec.rb +1 -1
- data/spec/rserve_rexp_wrapper_spec.rb +15 -1
- metadata +3 -3
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
!8��M���C�+G[I��j�8����%��\`k��"�H��}m������y�_�M��!ƩV9-�y�&�mL<��74>�B"{�CW�}â:__}����Y{��L�w{2�H���>�S�L�璛����52��H��,)4M�^�+Y���,p����ٝ�0/�^+<��$Ye����TWΏ�eܔ1��#�"�
|
data/History.txt
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
=== 0.2.1 / 2010-06-18
|
2
|
+
* Added suport to assign ruby std lib Matrix. Bug fix on retrieving matrix
|
3
|
+
* Fixed whitespace problem on README.txt
|
4
|
+
|
1
5
|
=== 0.2.0 / 2010-06-15
|
2
6
|
* Session implemented.
|
3
7
|
* Retrieve auth information from server first responde. TODO: Implement authentification
|
data/README.txt
CHANGED
@@ -15,19 +15,19 @@ Follows closely the new Java client API, but maintains all Ruby conventions when
|
|
15
15
|
* Uses TCP/IP sockets to interchange data and commands
|
16
16
|
* Requires Rserve installed on the server machine. On debian / ubuntu, you should use <tt>sudo apt-get install r-cran-rserve</tt>
|
17
17
|
Pros:
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
18
|
+
* Work with Ruby 1.8, 1.9 and JRuby 1.5.
|
19
|
+
* Work on Windows. Rserve limitations on that plataform applies (single connection, crash on parse errors)
|
20
|
+
* Retrieve and assign various R's datatypes: integer, doubles, chars, logical vectors, lists and raw data.
|
21
|
+
* Session allows to process data asynchronously. You start a command, detach the process and retrieve result later. You can marshall the session, store on file or database and use it when you need it.
|
22
|
+
* Ruby API follows closely the Java API, so any change on the server API could be adopted without much problem
|
23
|
+
* Fast: 5-10 times faster than RinRuby.
|
24
|
+
* Easy management of differences between R and Ruby, or "You can have your cake and eat it, too!"
|
25
|
+
* From R side: The evaluation of expression retrieves REXP object, with a lot of information from original variables on R. You can construct your REXP objects and <tt>assign</tt> them to variables on R fast using binary TCP/IP port or send complex expression without lost of time using <tt>void_eval</tt>
|
26
|
+
* Between R and Ruby: Every REXP object implements methods to convert to specific Ruby type: as_integers, as_doubles, as_strings
|
27
|
+
* From Ruby side: Every REXP objects has a <tt>to_ruby</tt> method, which automagicly converts every R type on equivalent Ruby type. So, a vector of size 1 is converted to an integer or double, a vector of size>1 returns an array, a named list returns a hash and so on. If you need to create a complex expression, you could always use method <tt>eval</tt> without problem
|
28
28
|
Cons:
|
29
|
-
|
30
|
-
|
29
|
+
* Requires Rserve
|
30
|
+
|
31
31
|
== RELATED LIBRARIES (Ruby / R)
|
32
32
|
|
33
33
|
* Rinruby [http://rinruby.ddahl.org/]
|
data/lib/rserve.rb
CHANGED
data/lib/rserve/rexp.rb
CHANGED
@@ -323,26 +323,31 @@ module Rserve
|
|
323
323
|
dim = get_attribute "dim"
|
324
324
|
raise MismatchException, "array (dim attribute missing" if dim.nil?
|
325
325
|
ds = dim.as_integers.reverse
|
326
|
-
|
327
326
|
split_array(ct,ds)
|
328
327
|
end
|
329
328
|
|
330
329
|
def split_array(ar, dims) # :nodoc:
|
331
|
-
#
|
330
|
+
#puts "#{ar} - #{dims}"
|
332
331
|
if dims.size==1
|
333
332
|
raise "Improper size ar:#{ar} , dims=#{dims[0]}" if ar.size!=dims[0]
|
334
333
|
return ar
|
335
334
|
elsif dims.size==2
|
335
|
+
dims.reverse!
|
336
336
|
# should rearrange values as R do
|
337
|
+
# dims[0]=cols, dims[1]=rows
|
338
|
+
if(true)
|
337
339
|
out=[]
|
338
340
|
ar.each_with_index {|v,i|
|
339
|
-
r=(i/dims[
|
340
|
-
c=i%dims[
|
341
|
-
#
|
342
|
-
out[c*dims[
|
341
|
+
r=(i/dims[0]).to_i;
|
342
|
+
c=i%dims[0];
|
343
|
+
#p "#{r} : #{c}";
|
344
|
+
out[c*dims[1]+r]=v
|
343
345
|
}
|
346
|
+
#p out
|
347
|
+
|
344
348
|
raise "out size should equal to ar size" if ar.size!=out.size
|
345
349
|
ar=out
|
350
|
+
end
|
346
351
|
end
|
347
352
|
dims_c=dims.dup
|
348
353
|
current_dim=dims_c.shift
|
data/lib/rserve/rexp/wrapper.rb
CHANGED
@@ -11,28 +11,45 @@ module Rserve
|
|
11
11
|
module Wrapper
|
12
12
|
def self.wrap(o)
|
13
13
|
return o if o.is_a? REXP
|
14
|
+
return o.to_REXP if o.respond_to? :to_REXP
|
14
15
|
case o
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
16
|
+
when TrueClass
|
17
|
+
REXP::Logical.new(1)
|
18
|
+
when FalseClass
|
19
|
+
REXP::Logical.new(0)
|
20
|
+
when NilClass
|
21
|
+
REXP::Null.new()
|
22
|
+
when ::String
|
23
|
+
REXP::String.new(o)
|
24
|
+
when Integer
|
25
|
+
REXP::Integer.new(o)
|
26
|
+
when Fixnum
|
27
|
+
REXP::Integer.new(o)
|
28
|
+
when Float
|
29
|
+
REXP::Double.new(o)
|
30
|
+
when Array
|
31
|
+
find_type_of_array(o)
|
32
|
+
when ::Matrix
|
33
|
+
create_matrix(o)
|
34
|
+
else
|
35
|
+
nil
|
34
36
|
end
|
35
37
|
end
|
38
|
+
def self.create_matrix(o)
|
39
|
+
data= o.column_size.times.map {|j|
|
40
|
+
o.column(j).to_a
|
41
|
+
}.flatten
|
42
|
+
attr=REXP::List.new(
|
43
|
+
Rlist.new(
|
44
|
+
[
|
45
|
+
REXP::String.new("matrix"),
|
46
|
+
REXP::Integer.new([o.row_size, o.column_size])
|
47
|
+
],
|
48
|
+
["class", "dim" ]
|
49
|
+
)
|
50
|
+
)
|
51
|
+
REXP::Double.new(data, attr)
|
52
|
+
end
|
36
53
|
def self.find_type_of_array(o)
|
37
54
|
if o.all? {|v| v.nil?}
|
38
55
|
REXP::Integer.new([REXP::Integer::NA]*o.size)
|
@@ -123,11 +123,21 @@ describe Rserve::Connection do
|
|
123
123
|
@r.eval("x").should==x
|
124
124
|
end
|
125
125
|
it "should assign a matrix" do
|
126
|
-
x=@r.eval("matrix(1:
|
126
|
+
x=@r.eval("matrix(1:12,6,2)")
|
127
127
|
@r.assign("x",x)
|
128
128
|
@r.eval("x").should==x
|
129
|
-
|
130
129
|
end
|
130
|
+
it "should assign a ruby matrix" do
|
131
|
+
mat_ruby=Matrix[[1,7],[2,8],[3,9],[4,10],[5,11],[6,12]]
|
132
|
+
@r.assign('x',mat_ruby)
|
133
|
+
x=@r.eval('x')
|
134
|
+
y=@r.eval('y<-matrix(c(1,2,3,4,5,6,7,8,9,10,11,12),6,2)')
|
135
|
+
#p x.attr.to_ruby
|
136
|
+
x.as_floats.should==y.as_floats
|
137
|
+
x.attr.as_list['dim'].should==y.attr.as_list['dim']
|
138
|
+
x.to_ruby.should==mat_ruby
|
139
|
+
end
|
140
|
+
|
131
141
|
after do
|
132
142
|
@r.void_eval("rm(x)")
|
133
143
|
end
|
@@ -38,7 +38,7 @@ describe "Rserve::REXP#to_ruby" do
|
|
38
38
|
a.attributes['names'].should==%w{a b c}
|
39
39
|
end
|
40
40
|
it "should return a Ruby Matrix with R matrix" do
|
41
|
-
@r.eval("matrix(c(1
|
41
|
+
@r.eval("matrix(c(1:12),6,2)").to_ruby.should==Matrix[[1,7],[2,8],[3,9],[4,10],[5,11], [6,12]]
|
42
42
|
end
|
43
43
|
it "should return a nested array of Ruby Matrixes with vector with more than tree dimensions" do
|
44
44
|
@r.void_eval("a<-1:16; attr(a,'dim')<-c(2,2,2,2)")
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require File.dirname(__FILE__)+"/spec_helper.rb"
|
2
|
-
|
2
|
+
require 'matrix'
|
3
3
|
describe Rserve::REXP::Wrapper do
|
4
4
|
it "should wrap single value" do
|
5
5
|
Rserve::REXP::Wrapper.wrap(1).should==Rserve::REXP::Integer.new(1)
|
@@ -13,6 +13,20 @@ describe Rserve::REXP::Wrapper do
|
|
13
13
|
Rserve::REXP::Wrapper.wrap([true,false]).should==Rserve::REXP::Logical.new([1,0])
|
14
14
|
Rserve::REXP::Wrapper.wrap(["a","b"]).should==Rserve::REXP::String.new(["a","b"])
|
15
15
|
end
|
16
|
+
it "should wrap a standard library matrix" do
|
17
|
+
mat=Matrix[[1,2],[3,4]]
|
18
|
+
expected=Rserve::REXP::Double.new([1,3,2,4], Rserve::REXP::List.new( Rserve::Rlist.new(
|
19
|
+
[
|
20
|
+
Rserve::REXP::String.new('matrix'),
|
21
|
+
Rserve::REXP::Integer.new([2,2])
|
22
|
+
],
|
23
|
+
['class','dim']
|
24
|
+
)
|
25
|
+
)
|
26
|
+
)
|
27
|
+
Rserve::REXP::Wrapper.wrap(mat).should==expected
|
28
|
+
end
|
29
|
+
|
16
30
|
it "should wrap on a list mixed values" do
|
17
31
|
r=Rserve::Connection.new
|
18
32
|
Rserve::REXP::Wrapper.wrap([1,2.0,false,"a"]).should==
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
version: 0.2.
|
8
|
+
- 1
|
9
|
+
version: 0.2.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Claudio Bustos
|
@@ -35,7 +35,7 @@ cert_chain:
|
|
35
35
|
rpP0jjs0
|
36
36
|
-----END CERTIFICATE-----
|
37
37
|
|
38
|
-
date: 2010-06-
|
38
|
+
date: 2010-06-18 00:00:00 -04:00
|
39
39
|
default_executable:
|
40
40
|
dependencies:
|
41
41
|
- !ruby/object:Gem::Dependency
|
metadata.gz.sig
CHANGED
Binary file
|