rserve-simpler 0.0.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/.document +5 -0
- data/Gemfile +16 -0
- data/Gemfile.lock +24 -0
- data/LICENSE.txt +21 -0
- data/README.rdoc +139 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/lib/rserve-simpler.rb +0 -0
- data/lib/rserve/data_frame.rb +49 -0
- data/lib/rserve/simpler.rb +77 -0
- data/lib/rserve/simpler/R.rb +3 -0
- data/rserve-simpler.gemspec +69 -0
- data/spec/rserve/simpler_spec.rb +126 -0
- data/spec/spec_helper.rb +12 -0
- metadata +150 -0
data/.document
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
# right now, using initialize code, so it is very version specific
|
7
|
+
gem "rserve-client", "~>0.2.5"
|
8
|
+
|
9
|
+
# Add dependencies to develop your gem here.
|
10
|
+
# Include everything needed to run rake, tests, features, etc.
|
11
|
+
group :development do
|
12
|
+
gem "spec-more", ">= 0"
|
13
|
+
gem "bundler", "~> 1.0.0"
|
14
|
+
gem "jeweler", "~> 1.5.2"
|
15
|
+
gem "rcov", ">= 0"
|
16
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
bacon (1.1.0)
|
5
|
+
git (1.2.5)
|
6
|
+
jeweler (1.5.2)
|
7
|
+
bundler (~> 1.0.0)
|
8
|
+
git (>= 1.2.5)
|
9
|
+
rake
|
10
|
+
rake (0.8.7)
|
11
|
+
rcov (0.9.9)
|
12
|
+
rserve-client (0.2.5)
|
13
|
+
spec-more (0.0.3)
|
14
|
+
bacon
|
15
|
+
|
16
|
+
PLATFORMS
|
17
|
+
ruby
|
18
|
+
|
19
|
+
DEPENDENCIES
|
20
|
+
bundler (~> 1.0.0)
|
21
|
+
jeweler (~> 1.5.2)
|
22
|
+
rcov
|
23
|
+
rserve-client (~> 0.2.5)
|
24
|
+
spec-more
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) 2011 Brigham Young University
|
2
|
+
Authored by John T. Prince
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
a copy of this software and associated documentation files (the
|
6
|
+
"Software"), to deal in the Software without restriction, including
|
7
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
= rserve-simpler
|
2
|
+
|
3
|
+
rserve-simpler is a simple interface on top of
|
4
|
+
{rserve-client}[https://github.com/clbustos/Rserve-Ruby-client], a fantastic
|
5
|
+
gem that lets a user communicate with R in a straighforward, efficient way.
|
6
|
+
|
7
|
+
{rserve-client}[https://github.com/clbustos/Rserve-Ruby-client] is doing all
|
8
|
+
the heavy lifting and should be consulted for background.
|
9
|
+
|
10
|
+
== Synposis
|
11
|
+
|
12
|
+
|
13
|
+
require 'rserve/simpler'
|
14
|
+
r = Rserve::Simpler.new
|
15
|
+
|
16
|
+
# or can initialize a connection held in the 'R' constant:
|
17
|
+
require 'rserve/simpler/R'
|
18
|
+
R.do_something_fantastic ... # ** not a real method
|
19
|
+
|
20
|
+
=== converse, convert, command
|
21
|
+
|
22
|
+
These commands specify ways of talking to your Rserve connection. All three
|
23
|
+
allow passing names through to R in a hash. They differ chiefly in the type
|
24
|
+
of output you'll receive back from R.
|
25
|
+
|
26
|
+
# converse: to_ruby the result
|
27
|
+
r.converse "mean(c(1,2,3))" # -> 2.0
|
28
|
+
|
29
|
+
# convert: Rserve::REXP result
|
30
|
+
rexp = r.convert "mean(c(1,2,3))" # -> #<Rserve::REXP::Double:0x00000002296498 @payload=[2.0], @attr=nil>
|
31
|
+
rexp.as_doubles # -> [2.0]
|
32
|
+
rexp.to_ruby # -> 2.0
|
33
|
+
|
34
|
+
# command: boolean reply if things went well
|
35
|
+
r.command "z <- mean(c(1,2,3))" # -> true
|
36
|
+
# can retrieve variables with converse
|
37
|
+
r.converse "z" # -> 2.0
|
38
|
+
|
39
|
+
converse/convert/command let you name variables in a hash as a shortcut to
|
40
|
+
'assign'. [These examples use Ruby 1.9 hash syntax, but they should work on
|
41
|
+
1.8 if the hashes are keyed old-style {:key => val}]
|
42
|
+
|
43
|
+
r.converse(a: [1,2,3], b: [4,5,6]) { "cor(a,b)" } # -> 1.0
|
44
|
+
# another form doing the same thing
|
45
|
+
r.converse("cor(a,b)", a: [1,2,3], b: [4,5,6])
|
46
|
+
|
47
|
+
==== prompt-like syntax '>>'
|
48
|
+
|
49
|
+
'>>' is an alias for converse, so you can write code like this:
|
50
|
+
|
51
|
+
r >> "mean(c(1,2,3))" # -> 2.0
|
52
|
+
# note: use '.' to get proper behavior with multiple args or blocks
|
53
|
+
r.>> "cor(a,b)", a: [1,2,3], b: [1,2,3]
|
54
|
+
|
55
|
+
=== simple DataFrame
|
56
|
+
|
57
|
+
==== with a hash
|
58
|
+
|
59
|
+
Column names are derived from hash keys (#keys). Ruby 1.9 hashes keep track
|
60
|
+
of insertion order. Use an OrderedHash (gem install orderedhash) for ruby
|
61
|
+
1.8, or set colnames.
|
62
|
+
|
63
|
+
hash = {
|
64
|
+
var1: [1,2,3,4],
|
65
|
+
fac1: [3,4,5,6],
|
66
|
+
res1: [4,5,6,7]
|
67
|
+
}
|
68
|
+
# convert with hash.to_dataframe or Rserve::DataFrame.new(hash)
|
69
|
+
r.command( df: hash.to_dataframe ) do
|
70
|
+
%Q{
|
71
|
+
pdf("out.pdf")
|
72
|
+
plot(df)
|
73
|
+
dev.off()
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
==== with an array of Structs
|
78
|
+
|
79
|
+
DataRow = Struct.new(:var1, :fac1, :res1)
|
80
|
+
structs = [
|
81
|
+
DataRow.new(1,3,4),
|
82
|
+
DataRow.new(2,4,5),
|
83
|
+
DataRow.new(3,5,6),
|
84
|
+
DataRow.new(4,6,7)
|
85
|
+
]
|
86
|
+
datafr = Rserve::DataFrame.from_structs(structs)
|
87
|
+
reply = r.converse("summary(df)", df: datafr).each_cons(6).to_a
|
88
|
+
datafr.colnames.zip(reply) {|name,data| puts [name].+(data).join("\n ") }
|
89
|
+
|
90
|
+
## outputs -> :
|
91
|
+
var1
|
92
|
+
Min. :1.00
|
93
|
+
1st Qu.:1.75
|
94
|
+
Median :2.50
|
95
|
+
Mean :2.50
|
96
|
+
3rd Qu.:3.25
|
97
|
+
Max. :4.00
|
98
|
+
fac1
|
99
|
+
Min. :3.00
|
100
|
+
1st Qu.:3.75
|
101
|
+
...
|
102
|
+
|
103
|
+
=== Notes on plotting
|
104
|
+
|
105
|
+
Rserve is great for graphical output. Here are some pointers when getting started with plotting:
|
106
|
+
|
107
|
+
==== plot to screen
|
108
|
+
|
109
|
+
r.command "plot(c(1,2,3), c(3,4,5))"
|
110
|
+
# if you resize a window (at least on Ubuntu) you may need to re-issue the call
|
111
|
+
r.command "plot(c(1,2,3), c(3,4,5))"
|
112
|
+
# return a list of currently used devices (device 2 is the only one being used)
|
113
|
+
# to_ruby returns an array of 1 value as a number
|
114
|
+
r.converse "dev.list()" # -> 2
|
115
|
+
# shut off graphics device 2
|
116
|
+
r.command "dev.off(2)"
|
117
|
+
r.command "graphics.off()" # shut off all graphics
|
118
|
+
|
119
|
+
==== plot to file
|
120
|
+
|
121
|
+
Files are written below the workdir specified when the Rserve connection was
|
122
|
+
made (see {Rserve configuration}[http://www.rforge.net/Rserve/doc.html#conf]
|
123
|
+
for background) and this is "/tmp/Rserve" on my system.
|
124
|
+
|
125
|
+
r.>> "pdf('output.pdf')", "plot(c(1,2,3),c(4,5,6))", "dev.off()"
|
126
|
+
# outputs file /tmp/Rserv/conn156/output.pdf
|
127
|
+
# note the connection number dir!
|
128
|
+
# (I haven't figured out how to predict this number)
|
129
|
+
|
130
|
+
== TODO
|
131
|
+
|
132
|
+
* simple option to use pwd as default directory
|
133
|
+
* quiet the startup of Rserve by default
|
134
|
+
* wrap graphic output commands
|
135
|
+
|
136
|
+
== Copyright
|
137
|
+
|
138
|
+
see LICENSE.txt
|
139
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
+
gem.name = "rserve-simpler"
|
16
|
+
gem.homepage = "http://github.com/jtprince/rserve-simpler"
|
17
|
+
gem.license = "MIT"
|
18
|
+
gem.summary = %Q{simple interface for interacting with R through Rserve}
|
19
|
+
gem.description = %Q{interface layered on top of rserve-client gem for interacting with R}
|
20
|
+
gem.email = "jtprince@gmail.com"
|
21
|
+
gem.authors = ["John Prince"]
|
22
|
+
# Include your dependencies below. Runtime dependencies are required when using your gem,
|
23
|
+
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
24
|
+
# gem.add_runtime_dependency 'jabber4r', '> 0.1'
|
25
|
+
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
26
|
+
end
|
27
|
+
Jeweler::RubygemsDotOrgTasks.new
|
28
|
+
|
29
|
+
require 'rake/testtask'
|
30
|
+
Rake::TestTask.new(:spec) do |spec|
|
31
|
+
spec.libs << 'lib' << 'spec'
|
32
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
33
|
+
spec.verbose = true
|
34
|
+
end
|
35
|
+
|
36
|
+
require 'rcov/rcovtask'
|
37
|
+
Rcov::RcovTask.new do |spec|
|
38
|
+
spec.libs << 'spec'
|
39
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
40
|
+
spec.verbose = true
|
41
|
+
end
|
42
|
+
|
43
|
+
task :default => :spec
|
44
|
+
|
45
|
+
require 'rake/rdoctask'
|
46
|
+
Rake::RDocTask.new do |rdoc|
|
47
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
48
|
+
|
49
|
+
rdoc.rdoc_dir = 'rdoc'
|
50
|
+
rdoc.title = "rserve-simpler #{version}"
|
51
|
+
rdoc.rdoc_files.include('README*')
|
52
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
53
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
File without changes
|
@@ -0,0 +1,49 @@
|
|
1
|
+
|
2
|
+
module Rserve
|
3
|
+
# An R-centric container for storing data frame-ish data
|
4
|
+
class DataFrame
|
5
|
+
attr_accessor :rownames
|
6
|
+
attr_accessor :hash
|
7
|
+
|
8
|
+
# takes an array of structs and returns a data frame object
|
9
|
+
def self.from_structs(array)
|
10
|
+
names = array.first.members
|
11
|
+
lengthwise_arrays = names.map { Array.new(names.size) }
|
12
|
+
array.each_with_index do |struct,m|
|
13
|
+
struct.values.each_with_index do |val,n|
|
14
|
+
lengthwise_arrays[n][m] = val
|
15
|
+
end
|
16
|
+
end
|
17
|
+
hash = {}
|
18
|
+
names.zip(lengthwise_arrays) do |name, lengthwise_array|
|
19
|
+
hash[name] = lengthwise_array
|
20
|
+
end
|
21
|
+
self.new(hash)
|
22
|
+
end
|
23
|
+
|
24
|
+
def colnames() @hash.keys end
|
25
|
+
|
26
|
+
# takes an ordered hash, where the col_name is the key and the data rows
|
27
|
+
# are an array of values. The default ordering of the hash keys will be
|
28
|
+
# used as the colnames. This works great for ruby 1.9 (which remembers
|
29
|
+
# ordering). Use an OrderedHash for ruby 1.8. The rownames can be used
|
30
|
+
# to specify the names of the rows (remains nil if no values specified)
|
31
|
+
def initialize(ordered_hash, rownames=nil)
|
32
|
+
@hash = ordered_hash
|
33
|
+
@rownames = rownames
|
34
|
+
end
|
35
|
+
|
36
|
+
def ==(other)
|
37
|
+
(self.hash == other.hash) && (self.rownames == other.rownames)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
class Hash
|
44
|
+
def to_dataframe(rownames=nil)
|
45
|
+
obj = Rserve::DataFrame.new(self)
|
46
|
+
obj.rownames = rownames if rownames
|
47
|
+
obj
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
|
2
|
+
require 'rserve'
|
3
|
+
require 'rserve/rexp'
|
4
|
+
require 'rserve/data_frame'
|
5
|
+
|
6
|
+
class Rserve::Simpler < Rserve::Connection
|
7
|
+
|
8
|
+
# assigns variables and returns an array of commands to be evaluated
|
9
|
+
def with(*args, &block)
|
10
|
+
if args.last.is_a? Hash
|
11
|
+
hash = args.pop # remove the hash
|
12
|
+
hash.each do |sym, obj|
|
13
|
+
rserve_compat_obj =
|
14
|
+
case obj
|
15
|
+
when Rserve::DataFrame
|
16
|
+
wrapped_lists = obj.hash.values.map {|v| Rserve::REXP::Wrapper.wrap(v) }
|
17
|
+
z = Rserve::Rlist.new(wrapped_lists, obj.hash.keys.map(&:to_s))
|
18
|
+
Rserve::REXP.create_data_frame(z)
|
19
|
+
else
|
20
|
+
obj
|
21
|
+
end
|
22
|
+
|
23
|
+
assign sym.to_s, rserve_compat_obj
|
24
|
+
|
25
|
+
# this is super hackish but I tried "correct" methods to do this
|
26
|
+
# and they do not want to work.
|
27
|
+
# TODO: roll creation of row.names into create_data_frame method
|
28
|
+
if obj.is_a?(Rserve::DataFrame) && obj.rownames
|
29
|
+
tmp_var = "#{sym}__rownames__tmp__"
|
30
|
+
# all rownames become string arrays:
|
31
|
+
assign tmp_var, Rserve::REXP::String.new(obj.rownames)
|
32
|
+
void_eval( ["row.names(#{sym}) <- #{tmp_var}", "rm(#{tmp_var})"].join("\n") )
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
to_eval = args
|
38
|
+
unless block.nil?
|
39
|
+
to_eval.push(*block.call)
|
40
|
+
end
|
41
|
+
to_eval
|
42
|
+
end
|
43
|
+
|
44
|
+
# eval and cast reply .to_ruby
|
45
|
+
#
|
46
|
+
# typically, a single string is passed in either as the first argument or
|
47
|
+
# with the block. The results of .to_ruby are passed back to the caller.
|
48
|
+
# However, if multiple strings are passed in (either as multiple string
|
49
|
+
# arguments or as multiple strings in the block, or one of each, etc.) the
|
50
|
+
# reply will be given as an array, one reply for each string.
|
51
|
+
def converse(*args, &block)
|
52
|
+
reply = with(*args, &block).map do |str|
|
53
|
+
response = self.eval(str)
|
54
|
+
reply = nil
|
55
|
+
begin ; reply = response.to_ruby
|
56
|
+
rescue ; reply = response
|
57
|
+
end
|
58
|
+
reply
|
59
|
+
end
|
60
|
+
(reply.size == 1) ? reply.first : reply
|
61
|
+
end
|
62
|
+
|
63
|
+
alias_method '>>'.to_sym, :converse
|
64
|
+
|
65
|
+
# void_eval
|
66
|
+
def command(*args, &block)
|
67
|
+
self.void_eval with(*args, &block).join("\n")
|
68
|
+
end
|
69
|
+
|
70
|
+
def convert(*args, &block)
|
71
|
+
reply = with(*args, &block).map do |str|
|
72
|
+
self.eval(str)
|
73
|
+
end
|
74
|
+
(reply.size == 1) ? reply.first : reply
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{rserve-simpler}
|
8
|
+
s.version = "0.0.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["John Prince"]
|
12
|
+
s.date = %q{2011-02-14}
|
13
|
+
s.description = %q{TODO: longer description of your gem}
|
14
|
+
s.email = %q{jtprince@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
"Gemfile",
|
22
|
+
"Gemfile.lock",
|
23
|
+
"LICENSE.txt",
|
24
|
+
"README.rdoc",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"lib/rserve-simpler.rb",
|
28
|
+
"lib/rserve/data_frame.rb",
|
29
|
+
"lib/rserve/simpler.rb",
|
30
|
+
"lib/rserve/simpler/R.rb",
|
31
|
+
"spec/rserve/simpler_spec.rb",
|
32
|
+
"spec/spec_helper.rb"
|
33
|
+
]
|
34
|
+
s.homepage = %q{http://github.com/jtprince/rserve-simpler}
|
35
|
+
s.licenses = ["MIT"]
|
36
|
+
s.require_paths = ["lib"]
|
37
|
+
s.rubygems_version = %q{1.3.7}
|
38
|
+
s.summary = %q{TODO: one-line summary of your gem}
|
39
|
+
s.test_files = [
|
40
|
+
"spec/rserve/simpler_spec.rb",
|
41
|
+
"spec/spec_helper.rb"
|
42
|
+
]
|
43
|
+
|
44
|
+
if s.respond_to? :specification_version then
|
45
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
46
|
+
s.specification_version = 3
|
47
|
+
|
48
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
49
|
+
s.add_runtime_dependency(%q<rserve-client>, ["~> 0.2.5"])
|
50
|
+
s.add_development_dependency(%q<spec-more>, [">= 0"])
|
51
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
52
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
|
53
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
54
|
+
else
|
55
|
+
s.add_dependency(%q<rserve-client>, ["~> 0.2.5"])
|
56
|
+
s.add_dependency(%q<spec-more>, [">= 0"])
|
57
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
58
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
59
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
60
|
+
end
|
61
|
+
else
|
62
|
+
s.add_dependency(%q<rserve-client>, ["~> 0.2.5"])
|
63
|
+
s.add_dependency(%q<spec-more>, [">= 0"])
|
64
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
65
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
66
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'rserve/simpler'
|
4
|
+
|
5
|
+
describe "initializing a connection held in 'R'" do
|
6
|
+
it 'require "rserve/simpler/R" # loads a connection into R' do
|
7
|
+
require 'rserve/simpler/R'
|
8
|
+
R.converse("mean(c(1,2,3))").is 2.0
|
9
|
+
R.close
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe 'rserve connection with simpler' do
|
14
|
+
xit 'is quiet on startup' do
|
15
|
+
@r = Rserve::Simpler.new
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe 'rserve connection with simpler additions' do
|
20
|
+
|
21
|
+
before do
|
22
|
+
@r = Rserve::Simpler.new
|
23
|
+
end
|
24
|
+
|
25
|
+
after do
|
26
|
+
@r.close
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'converses with R using strings' do
|
30
|
+
# both sides speak native
|
31
|
+
ok @r.connected?
|
32
|
+
reply = @r.converse "mean(c(1,2,3))"
|
33
|
+
@r.converse("mean(c(1,2,3))").is 2.0
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'converses with R using arrays and numbers' do
|
37
|
+
@r.converse("cor(a,b)", :a => [1,2,3], :b => [4,5,6]).is 1.0
|
38
|
+
@r.converse(:a => [1,2,3], :b => [4,5,6]) { "cor(a,b)" }.is 1.0
|
39
|
+
@r.converse(:a => 3) { "mean(a)" }.is 3.0
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'can converse in sentences' do
|
43
|
+
(mean, cor) = @r.converse("mean(a)", "cor(a,b)", :a => [1,2,3], :b => [4,5,6])
|
44
|
+
mean.is 2.0
|
45
|
+
cor.is 1.0
|
46
|
+
# not sure why you'd want to do this, but this is okay
|
47
|
+
(mean, cor) = @r.converse("mean(a)") { "cor(a,b)" }
|
48
|
+
# also okay
|
49
|
+
(mean, cor) = @r.converse "mean(a)", "cor(a,b)"
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'has a prompt-like syntax' do
|
53
|
+
reply = @r >> "mean(c(1,2,3))"
|
54
|
+
reply.is 2.0
|
55
|
+
reply = @r.>> "cor(a,b)", a: [1,2,3], b: [1,2,3]
|
56
|
+
reply.is 1.0
|
57
|
+
end
|
58
|
+
|
59
|
+
it "commands R (giving no response but 'true')" do
|
60
|
+
@r.command(:a => [1,2,3], :b => [4,5,6]) { "z = cor(a,b)" }.is true
|
61
|
+
@r.converse("z").is 1.0
|
62
|
+
end
|
63
|
+
|
64
|
+
it "convert to REXP" do
|
65
|
+
reply = @r.convert(:a => [1,2,3], :b => [4,5,6]) { "cor(a,b)" }
|
66
|
+
ok reply.is_a?(Rserve::REXP::Double)
|
67
|
+
reply.as_doubles.is [1.0]
|
68
|
+
reply.to_ruby .is 1.0
|
69
|
+
end
|
70
|
+
|
71
|
+
xit "returns the REXP if to_ruby raises an error" do
|
72
|
+
# still need to test this
|
73
|
+
flunk
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
if RUBY_VERSION > '1.9'
|
79
|
+
|
80
|
+
# TODO: write these compatible for 1.8
|
81
|
+
|
82
|
+
describe 'rserve with DataFrame convenience functions' do
|
83
|
+
|
84
|
+
Row = Struct.new(:fac1, :var1, :res1)
|
85
|
+
|
86
|
+
before do
|
87
|
+
@r = Rserve::Simpler.new
|
88
|
+
@hash = {:fac1 => [1,2,3,4], :var1 => [4,5,6,7], :res1 => [8,9,10,11]}
|
89
|
+
@colnames = %w(fac1 var1 res1).map(&:to_sym)
|
90
|
+
@ar_of_structs = [Row.new(1,4,8), Row.new(2,5,9), Row.new(3,6,10), Row.new(4,7,11)]
|
91
|
+
end
|
92
|
+
|
93
|
+
after do
|
94
|
+
@r.close
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'gives hashes a .to_dataframe method' do
|
98
|
+
# only need to set the colnames with Ruby 1.8 (unless using OrderedHash)
|
99
|
+
df1 = Rserve::DataFrame.new(@hash)
|
100
|
+
df2 = @hash.to_dataframe
|
101
|
+
df2.colnames.is @colnames
|
102
|
+
df1.is df2
|
103
|
+
df2.colnames.is @colnames
|
104
|
+
df2.rownames.is nil
|
105
|
+
df2.rownames = [1,2,3,4]
|
106
|
+
df2.rownames.is [1,2,3,4]
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'converts an array of parallel structs into a dataframe' do
|
110
|
+
df = Rserve::DataFrame.from_structs( @ar_of_structs )
|
111
|
+
df.is @hash.to_dataframe
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'accepts simple dataframes when conversing with R' do
|
115
|
+
@r.converse(:df => @hash.to_dataframe) { "names(df)" }.is %w(fac1 var1 res1)
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'accepts dataframes with rownames when conversing with R' do
|
119
|
+
rownames = [11,12,13,14]
|
120
|
+
@r.converse(:df => @hash.to_dataframe(rownames)) { "row.names(df)" }.is rownames.map(&:to_s)
|
121
|
+
rownames = %w(row1 row2 row3 row4)
|
122
|
+
@r.converse(:df => @hash.to_dataframe(rownames)) { "row.names(df)" }.is rownames
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'spec/more'
|
11
|
+
|
12
|
+
Bacon.summary_on_exit
|
metadata
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rserve-simpler
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- John Prince
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-02-14 00:00:00 -07:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rserve-client
|
22
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
23
|
+
none: false
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
- 2
|
30
|
+
- 5
|
31
|
+
version: 0.2.5
|
32
|
+
type: :runtime
|
33
|
+
prerelease: false
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: spec-more
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
segments:
|
43
|
+
- 0
|
44
|
+
version: "0"
|
45
|
+
type: :development
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: bundler
|
50
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ~>
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
segments:
|
56
|
+
- 1
|
57
|
+
- 0
|
58
|
+
- 0
|
59
|
+
version: 1.0.0
|
60
|
+
type: :development
|
61
|
+
prerelease: false
|
62
|
+
version_requirements: *id003
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: jeweler
|
65
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ~>
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
segments:
|
71
|
+
- 1
|
72
|
+
- 5
|
73
|
+
- 2
|
74
|
+
version: 1.5.2
|
75
|
+
type: :development
|
76
|
+
prerelease: false
|
77
|
+
version_requirements: *id004
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rcov
|
80
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
segments:
|
86
|
+
- 0
|
87
|
+
version: "0"
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *id005
|
91
|
+
description: interface layered on top of rserve-client gem for interacting with R
|
92
|
+
email: jtprince@gmail.com
|
93
|
+
executables: []
|
94
|
+
|
95
|
+
extensions: []
|
96
|
+
|
97
|
+
extra_rdoc_files:
|
98
|
+
- LICENSE.txt
|
99
|
+
- README.rdoc
|
100
|
+
files:
|
101
|
+
- .document
|
102
|
+
- Gemfile
|
103
|
+
- Gemfile.lock
|
104
|
+
- LICENSE.txt
|
105
|
+
- README.rdoc
|
106
|
+
- Rakefile
|
107
|
+
- VERSION
|
108
|
+
- lib/rserve-simpler.rb
|
109
|
+
- lib/rserve/data_frame.rb
|
110
|
+
- lib/rserve/simpler.rb
|
111
|
+
- lib/rserve/simpler/R.rb
|
112
|
+
- rserve-simpler.gemspec
|
113
|
+
- spec/rserve/simpler_spec.rb
|
114
|
+
- spec/spec_helper.rb
|
115
|
+
has_rdoc: true
|
116
|
+
homepage: http://github.com/jtprince/rserve-simpler
|
117
|
+
licenses:
|
118
|
+
- MIT
|
119
|
+
post_install_message:
|
120
|
+
rdoc_options: []
|
121
|
+
|
122
|
+
require_paths:
|
123
|
+
- lib
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
125
|
+
none: false
|
126
|
+
requirements:
|
127
|
+
- - ">="
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
hash: -3232687242390354005
|
130
|
+
segments:
|
131
|
+
- 0
|
132
|
+
version: "0"
|
133
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
|
+
none: false
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
segments:
|
139
|
+
- 0
|
140
|
+
version: "0"
|
141
|
+
requirements: []
|
142
|
+
|
143
|
+
rubyforge_project:
|
144
|
+
rubygems_version: 1.3.7
|
145
|
+
signing_key:
|
146
|
+
specification_version: 3
|
147
|
+
summary: simple interface for interacting with R through Rserve
|
148
|
+
test_files:
|
149
|
+
- spec/rserve/simpler_spec.rb
|
150
|
+
- spec/spec_helper.rb
|