rust 0.7 → 0.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/ruby-rust +3 -0
- data/lib/{rust-csv.rb → rust/core/csv.rb} +23 -1
- data/lib/rust/core/rust.rb +221 -0
- data/lib/rust/core/types/all.rb +4 -0
- data/lib/{rust-core.rb → rust/core/types/dataframe.rb} +159 -331
- data/lib/rust/core/types/datatype.rb +195 -0
- data/lib/rust/core/types/factor.rb +158 -0
- data/lib/rust/core/types/language.rb +199 -0
- data/lib/rust/core/types/list.rb +97 -0
- data/lib/rust/core/types/matrix.rb +155 -0
- data/lib/rust/core/types/s4class.rb +78 -0
- data/lib/rust/core/types/utils.rb +122 -0
- data/lib/rust/core.rb +7 -0
- data/lib/rust/external/robustbase.rb +44 -0
- data/lib/rust/models/all.rb +4 -0
- data/lib/rust/models/anova.rb +77 -0
- data/lib/rust/models/regression.rb +258 -0
- data/lib/rust/plots/all.rb +4 -0
- data/lib/rust/plots/basic-plots.rb +143 -0
- data/lib/{rust-plots.rb → rust/plots/core.rb} +89 -167
- data/lib/rust/plots/distribution-plots.rb +75 -0
- data/lib/rust/stats/all.rb +4 -0
- data/lib/{rust-basics.rb → rust/stats/correlation.rb} +45 -2
- data/lib/{rust-descriptive.rb → rust/stats/descriptive.rb} +52 -3
- data/lib/{rust-effsize.rb → rust/stats/effsize.rb} +28 -13
- data/lib/{rust-probabilities.rb → rust/stats/probabilities.rb} +142 -34
- data/lib/{rust-tests.rb → rust/stats/tests.rb} +178 -92
- data/lib/rust.rb +4 -9
- metadata +32 -13
- data/lib/rust-calls.rb +0 -80
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 77dee9cb8c4a1e2894a8054fab8dbf140b8f6a4aed8ef38a60b41564fb5e8e69
|
4
|
+
data.tar.gz: c9bf14d2239f464cf73ffaee86bcbfe9155a323269eff1b34b7bcd1272c46d36
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a648f440574e7734f979c0ec5d65bc9594202cfe88414517dcc50482e391360809ced88bbc0b825f548dfd23dd2b9dfe47b71cabbd216249d992d8a18d14717c
|
7
|
+
data.tar.gz: 1b999d94b96c05a0615ff05b3e1588c4a8e822baebba57055ae041a6fe2c7d0355d747e3c88973c9325046c59c4eff013b27336d95297c8c0e1cc06f515b2f27
|
data/bin/ruby-rust
ADDED
@@ -1,7 +1,17 @@
|
|
1
|
-
require_relative '
|
1
|
+
require_relative '../core'
|
2
|
+
require 'csv'
|
2
3
|
|
3
4
|
module Rust
|
5
|
+
|
6
|
+
##
|
7
|
+
# Class that handles CSVs (both loading and saving).
|
8
|
+
|
4
9
|
class CSV
|
10
|
+
|
11
|
+
##
|
12
|
+
# Reads a +pattern+ of CSVs (glob-style pattern) and returns a map containing as keys the filenames of the
|
13
|
+
# loaded CSVs and as values the corresponding data-frames. Options can be specified (see #read).
|
14
|
+
|
5
15
|
def self.read_all(pattern, **options)
|
6
16
|
result = DataFrameHash.new
|
7
17
|
Dir.glob(pattern).each do |filename|
|
@@ -10,6 +20,13 @@ module Rust
|
|
10
20
|
return result
|
11
21
|
end
|
12
22
|
|
23
|
+
##
|
24
|
+
# Reads the CSV at +filename+. Options can be specified, such as:
|
25
|
+
# - headers => set to true if the first row contains the headers, false otherwise;
|
26
|
+
# - infer_numbers => if a column contains only numbers, the values are transformed into floats; true by default;
|
27
|
+
# - infer_integers => if infer_numbers is active, it distinguishes between integers and floats;
|
28
|
+
# The other options are the ones that can be used in the function R function "read.csv".
|
29
|
+
|
13
30
|
def self.read(filename, **options)
|
14
31
|
hash = {}
|
15
32
|
labels = nil
|
@@ -45,6 +62,11 @@ module Rust
|
|
45
62
|
return result
|
46
63
|
end
|
47
64
|
|
65
|
+
##
|
66
|
+
# Writes the +dataframe+ as a CSV at +filename+. Options can be specified, such as:
|
67
|
+
# - headers => set to true if the first row should contain the headers, false otherwise;
|
68
|
+
# The other options are the ones that can be used in the function R function "read.csv".
|
69
|
+
|
48
70
|
def self.write(filename, dataframe, **options)
|
49
71
|
raise TypeError, "Expected Rust::DataFrame" unless dataframe.is_a?(Rust::DataFrame)
|
50
72
|
|
@@ -0,0 +1,221 @@
|
|
1
|
+
require 'code-assertions'
|
2
|
+
require 'stringio'
|
3
|
+
require 'rinruby'
|
4
|
+
|
5
|
+
##
|
6
|
+
# Basic module for the Rust package. It includes a series of sub-modules that provide specific features, such as
|
7
|
+
# statistical hypothesis tests, plots, and so on.
|
8
|
+
|
9
|
+
module Rust
|
10
|
+
CLIENT_MUTEX = Mutex.new
|
11
|
+
R_MUTEX = Mutex.new
|
12
|
+
|
13
|
+
R_ENGINE = RinRuby.new(echo: false)
|
14
|
+
|
15
|
+
private_constant :R_ENGINE
|
16
|
+
private_constant :R_MUTEX
|
17
|
+
private_constant :CLIENT_MUTEX
|
18
|
+
|
19
|
+
@@debugging = $RUST_DEBUG || false
|
20
|
+
@@in_client_mutex = false
|
21
|
+
|
22
|
+
##
|
23
|
+
# Sets the debug mode. Any call to R will be written on the standard output.
|
24
|
+
|
25
|
+
def self.debug
|
26
|
+
@@debugging = true
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Checks if the debug mode is active.
|
31
|
+
|
32
|
+
def self.debug?
|
33
|
+
return @@debugging
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# Runs the given block with a mutex. It is mandatory to run any R command with this method.
|
38
|
+
|
39
|
+
def self.exclusive
|
40
|
+
result = nil
|
41
|
+
CLIENT_MUTEX.synchronize do
|
42
|
+
@@in_client_mutex = true
|
43
|
+
result = yield
|
44
|
+
@@in_client_mutex = false
|
45
|
+
end
|
46
|
+
return result
|
47
|
+
end
|
48
|
+
|
49
|
+
##
|
50
|
+
# Sets a variable in the R environment with a given value.
|
51
|
+
#
|
52
|
+
# Raises an error if the value can not be translated into an R object.
|
53
|
+
#
|
54
|
+
# Example: Rust['a'] = 0.
|
55
|
+
|
56
|
+
def self.[]=(variable, value)
|
57
|
+
if value.is_a?(RustDatatype)
|
58
|
+
value.load_in_r_as(variable.to_s)
|
59
|
+
elsif value.is_a?(String) || value.is_a?(Numeric) || value.is_a?(Array) || value.is_a?(::Matrix)
|
60
|
+
R_ENGINE.assign(variable, value)
|
61
|
+
else
|
62
|
+
raise "Trying to assign #{variable} with #{value.class}; expected RustDatatype, String, Numeric, or Array"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
##
|
67
|
+
# Retrieves the value of a variable from the R environment.
|
68
|
+
#
|
69
|
+
# Example: Rust['a']
|
70
|
+
|
71
|
+
def self.[](variable)
|
72
|
+
return RustDatatype.pull_variable(variable)
|
73
|
+
end
|
74
|
+
|
75
|
+
def self._eval_big(r_command, return_warnings = false)
|
76
|
+
r_command = r_command.join("\n") if r_command.is_a?(Array)
|
77
|
+
|
78
|
+
self._rexec(r_command, return_warnings) do |cmd|
|
79
|
+
result = true
|
80
|
+
instructions = cmd.lines
|
81
|
+
|
82
|
+
while instructions.size > 0
|
83
|
+
current_command = ""
|
84
|
+
|
85
|
+
while (instructions.size > 0) && (current_command.length + instructions.first.length < 10000)
|
86
|
+
current_command << instructions.shift
|
87
|
+
end
|
88
|
+
|
89
|
+
result &= R_ENGINE.eval(current_command)
|
90
|
+
end
|
91
|
+
|
92
|
+
result
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def self._pull(r_command, return_warnings = false)
|
97
|
+
self._rexec(r_command, return_warnings) { |cmd| R_ENGINE.pull(cmd) }
|
98
|
+
end
|
99
|
+
|
100
|
+
def self._eval(r_command, return_warnings = false)
|
101
|
+
self._rexec(r_command, return_warnings) { |cmd| R_ENGINE.eval(cmd) }
|
102
|
+
end
|
103
|
+
|
104
|
+
def self._rexec(r_command, return_warnings = false)
|
105
|
+
puts "Calling _rexec with command: #{r_command}" if @@debugging
|
106
|
+
R_MUTEX.synchronize do
|
107
|
+
assert("This command must be executed in an exclusive block") { @@in_client_mutex }
|
108
|
+
|
109
|
+
result = nil
|
110
|
+
begin
|
111
|
+
$stdout = StringIO.new
|
112
|
+
if return_warnings
|
113
|
+
R_ENGINE.echo(true, true)
|
114
|
+
else
|
115
|
+
R_ENGINE.echo(false, false)
|
116
|
+
end
|
117
|
+
result = yield(r_command)
|
118
|
+
ensure
|
119
|
+
R_ENGINE.echo(false, false)
|
120
|
+
warnings = $stdout.string
|
121
|
+
$stdout = STDOUT
|
122
|
+
end
|
123
|
+
|
124
|
+
if return_warnings
|
125
|
+
puts " Got #{warnings.size} warnings, with result #{result.inspect[0...100]}" if @@debugging
|
126
|
+
return result, warnings.lines.map { |w| w.strip.chomp }
|
127
|
+
else
|
128
|
+
puts " Result: #{result.inspect[0...100]}" if @@debugging
|
129
|
+
return result
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
##
|
135
|
+
# Checks if the given +name+ library can be used. Returns true if it is available, false otherwise.
|
136
|
+
|
137
|
+
def self.check_library(name)
|
138
|
+
self.exclusive do
|
139
|
+
result, _ = self._pull("require(\"#{name}\", character.only = TRUE)", true)
|
140
|
+
return result
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
##
|
145
|
+
# Loads the given +name+ library.
|
146
|
+
|
147
|
+
def self.load_library(name)
|
148
|
+
self.exclusive do
|
149
|
+
self._eval("library(\"#{name}\", character.only = TRUE)")
|
150
|
+
end
|
151
|
+
|
152
|
+
return nil
|
153
|
+
end
|
154
|
+
|
155
|
+
##
|
156
|
+
# Installs the given +name+ library and its dependencies.
|
157
|
+
|
158
|
+
def self.install_library(name)
|
159
|
+
self.exclusive do
|
160
|
+
self._eval("install.packages(\"#{name}\", dependencies = TRUE)")
|
161
|
+
end
|
162
|
+
|
163
|
+
return nil
|
164
|
+
end
|
165
|
+
|
166
|
+
##
|
167
|
+
# Installs the +library+ library if it is not available and loads it.
|
168
|
+
|
169
|
+
def self.prerequisite(library)
|
170
|
+
self.install_library(library) unless self.check_library(library)
|
171
|
+
self.load_library(library)
|
172
|
+
end
|
173
|
+
|
174
|
+
##
|
175
|
+
# Ask for help on a given +mod+.
|
176
|
+
|
177
|
+
def self.help!(mod = nil)
|
178
|
+
unless mod
|
179
|
+
puts "You have the following modules:"
|
180
|
+
Rust.constants.map { |c| Rust.const_get(c) }.select { |c| c.class == Module }.each do |mod|
|
181
|
+
puts "\t- #{mod}"
|
182
|
+
end
|
183
|
+
puts "Run \"help! {module}\" for more detailed information about the module"
|
184
|
+
else
|
185
|
+
if mod.methods.include?(:help!)
|
186
|
+
mod.help!
|
187
|
+
else
|
188
|
+
puts "Sorry, no help available for #{mod}"
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
##
|
195
|
+
# Module that contains methods that allow to call R functions faster. Such methods have names resembling the ones
|
196
|
+
# available in R (e.g., cor, wilcox_test).
|
197
|
+
|
198
|
+
module Rust::RBindings
|
199
|
+
def data_frame(*args)
|
200
|
+
Rust::DataFrame.new(*args)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
module Rust::TestCases
|
205
|
+
def self.sample_dataframe(columns, size=100)
|
206
|
+
result = Rust::DataFrame.new(columns)
|
207
|
+
size.times do |i|
|
208
|
+
result << columns.map { |c| yield i, c }
|
209
|
+
end
|
210
|
+
return result
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
##
|
215
|
+
# Shortcut for including the RBinding module
|
216
|
+
|
217
|
+
def bind_r!
|
218
|
+
include Rust::RBindings
|
219
|
+
end
|
220
|
+
|
221
|
+
bind_r! if ENV['RUBY_RUST_BINDING'] == '1'
|