rust 0.9 → 0.10
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 +4 -4
- data/bin/ruby-rust +1 -1
- data/lib/rust/core/csv.rb +21 -0
- data/lib/rust/core/rust.rb +65 -1
- data/lib/rust/core/types/dataframe.rb +146 -0
- data/lib/rust/core/types/datatype.rb +34 -0
- data/lib/rust/core/types/factor.rb +27 -0
- data/lib/rust/core/types/language.rb +44 -11
- data/lib/rust/core/types/list.rb +16 -0
- data/lib/rust/core/types/matrix.rb +29 -6
- data/lib/rust/core/types/s4class.rb +19 -0
- data/lib/rust/core/types/utils.rb +14 -1
- data/lib/rust/models/anova.rb +17 -0
- data/lib/rust/models/regression.rb +54 -1
- data/lib/rust/plots/basic-plots.rb +32 -0
- data/lib/rust/plots/core.rb +90 -0
- data/lib/rust/plots/distribution-plots.rb +13 -0
- data/lib/rust/stats/correlation.rb +43 -0
- data/lib/rust/stats/descriptive.rb +29 -0
- data/lib/rust/stats/effsize.rb +21 -0
- data/lib/rust/stats/probabilities.rb +141 -33
- data/lib/rust/stats/tests.rb +97 -5
- metadata +2 -2
data/lib/rust/plots/core.rb
CHANGED
@@ -1,25 +1,45 @@
|
|
1
1
|
require_relative '../core'
|
2
2
|
|
3
|
+
##
|
4
|
+
# Module that contains classes for plotting.
|
5
|
+
|
3
6
|
module Rust::Plots
|
7
|
+
|
8
|
+
##
|
9
|
+
# Represents a generic plot in R.
|
10
|
+
|
4
11
|
class BasePlot
|
12
|
+
|
13
|
+
##
|
14
|
+
# Creates a new base plot object.
|
15
|
+
|
5
16
|
def initialize
|
6
17
|
@renderables = []
|
7
18
|
@options = Rust::Options.new
|
8
19
|
@override_options = true
|
9
20
|
end
|
10
21
|
|
22
|
+
##
|
23
|
+
# Sets the x-axis label.
|
24
|
+
|
11
25
|
def x_label(label)
|
12
26
|
@options['xlab'] = label
|
13
27
|
|
14
28
|
return self
|
15
29
|
end
|
16
30
|
|
31
|
+
##
|
32
|
+
# Sets the y-axis label.
|
33
|
+
|
17
34
|
def y_label(label)
|
18
35
|
@options['ylab'] = label
|
19
36
|
|
20
37
|
return self
|
21
38
|
end
|
22
39
|
|
40
|
+
##
|
41
|
+
# Returns a color palette of the given +size+.
|
42
|
+
|
23
43
|
def palette(size)
|
24
44
|
if size <= 1
|
25
45
|
return ['black']
|
@@ -28,17 +48,28 @@ module Rust::Plots
|
|
28
48
|
end
|
29
49
|
end
|
30
50
|
|
51
|
+
##
|
52
|
+
# Sets the limits for the x-axis.
|
53
|
+
|
31
54
|
def x_range(range)
|
32
55
|
@options['xlim'] = range
|
33
56
|
|
34
57
|
return self
|
35
58
|
end
|
59
|
+
alias :xlim :x_range
|
60
|
+
|
61
|
+
##
|
62
|
+
# Sets the limits for the y-axis.
|
36
63
|
|
37
64
|
def y_range(range)
|
38
65
|
@options['ylim'] = range
|
39
66
|
|
40
67
|
return self
|
41
68
|
end
|
69
|
+
alias :ylim :y_range
|
70
|
+
|
71
|
+
##
|
72
|
+
# Adds an +axis+ to show instead of the default ones.
|
42
73
|
|
43
74
|
def axis(axis)
|
44
75
|
@options['xaxt'] = 'n'
|
@@ -49,18 +80,27 @@ module Rust::Plots
|
|
49
80
|
return self
|
50
81
|
end
|
51
82
|
|
83
|
+
##
|
84
|
+
# Shows the given +grid+.
|
85
|
+
|
52
86
|
def grid(grid)
|
53
87
|
self._add_renderable(grid)
|
54
88
|
|
55
89
|
return self
|
56
90
|
end
|
57
91
|
|
92
|
+
##
|
93
|
+
# Sets the +title+ of the plot.
|
94
|
+
|
58
95
|
def title(title)
|
59
96
|
@options['main'] = title
|
60
97
|
|
61
98
|
return self
|
62
99
|
end
|
63
100
|
|
101
|
+
##
|
102
|
+
# Sets the +color+ of the plot.
|
103
|
+
|
64
104
|
def color(color)
|
65
105
|
@options['col'] = color
|
66
106
|
|
@@ -74,6 +114,9 @@ module Rust::Plots
|
|
74
114
|
return self
|
75
115
|
end
|
76
116
|
|
117
|
+
##
|
118
|
+
# Sets any R +option+ with the given +value+.
|
119
|
+
|
77
120
|
def []=(option, value)
|
78
121
|
@options[option.to_s] = value
|
79
122
|
end
|
@@ -82,6 +125,9 @@ module Rust::Plots
|
|
82
125
|
@override_options = false
|
83
126
|
end
|
84
127
|
|
128
|
+
##
|
129
|
+
# Shows the plot in a window.
|
130
|
+
|
85
131
|
def show()
|
86
132
|
Rust.exclusive do
|
87
133
|
self._show
|
@@ -91,6 +137,9 @@ module Rust::Plots
|
|
91
137
|
return self
|
92
138
|
end
|
93
139
|
|
140
|
+
##
|
141
|
+
# Prints the plot on a PDF file at path. +options+ can be specified for the PDF (e.g., width and height).
|
142
|
+
|
94
143
|
def pdf(path, **options)
|
95
144
|
pdf_function = Rust::Function.new("pdf")
|
96
145
|
pdf_function.options = Rust::Options.from_hash(options)
|
@@ -133,11 +182,21 @@ module Rust::Plots
|
|
133
182
|
end
|
134
183
|
end
|
135
184
|
|
185
|
+
##
|
186
|
+
# Represents any element that can be rendered in a plot (e.g., axes or grids).
|
187
|
+
|
136
188
|
class Renderable
|
189
|
+
|
190
|
+
##
|
191
|
+
# Creates a new empty renderable object.
|
192
|
+
|
137
193
|
def initialize
|
138
194
|
@options = Rust::Options.new
|
139
195
|
end
|
140
196
|
|
197
|
+
##
|
198
|
+
# Sets an option for the renderable object.
|
199
|
+
|
141
200
|
def []=(option, value)
|
142
201
|
@options[option] = value
|
143
202
|
|
@@ -150,12 +209,18 @@ module Rust::Plots
|
|
150
209
|
end
|
151
210
|
end
|
152
211
|
|
212
|
+
##
|
213
|
+
# Represents an axis for a plot.
|
214
|
+
|
153
215
|
class Axis < Renderable
|
154
216
|
BELOW = 1
|
155
217
|
LEFT = 2
|
156
218
|
ABOVE = 3
|
157
219
|
RIGHT = 4
|
158
220
|
|
221
|
+
##
|
222
|
+
# Creates a new axis at the given +side+ (constants BELOW, LEFT, ABOVE, and RIGHT are available).
|
223
|
+
|
159
224
|
def initialize(side)
|
160
225
|
super()
|
161
226
|
|
@@ -198,7 +263,14 @@ module Rust::Plots
|
|
198
263
|
end
|
199
264
|
end
|
200
265
|
|
266
|
+
##
|
267
|
+
# Represents a grid for a plot.
|
268
|
+
|
201
269
|
class Grid < Renderable
|
270
|
+
|
271
|
+
##
|
272
|
+
# Creates a new grid
|
273
|
+
|
202
274
|
def initialize
|
203
275
|
super()
|
204
276
|
|
@@ -206,36 +278,54 @@ module Rust::Plots
|
|
206
278
|
@y = Float::NAN
|
207
279
|
end
|
208
280
|
|
281
|
+
##
|
282
|
+
# Sets the x intervals.
|
283
|
+
|
209
284
|
def x(value)
|
210
285
|
@x = value
|
211
286
|
|
212
287
|
return self
|
213
288
|
end
|
214
289
|
|
290
|
+
##
|
291
|
+
# Sets the y intervals.
|
292
|
+
|
215
293
|
def y(value)
|
216
294
|
@y = value
|
217
295
|
|
218
296
|
return self
|
219
297
|
end
|
220
298
|
|
299
|
+
##
|
300
|
+
# Automatically sets the x intervals.
|
301
|
+
|
221
302
|
def auto_x
|
222
303
|
@x = nil
|
223
304
|
|
224
305
|
return self
|
225
306
|
end
|
226
307
|
|
308
|
+
##
|
309
|
+
# Automatically sets the y intervals.
|
310
|
+
|
227
311
|
def auto_y
|
228
312
|
@y = nil
|
229
313
|
|
230
314
|
return self
|
231
315
|
end
|
232
316
|
|
317
|
+
##
|
318
|
+
# Hides x axis lines.
|
319
|
+
|
233
320
|
def hide_x
|
234
321
|
@x = Float::NAN
|
235
322
|
|
236
323
|
return self
|
237
324
|
end
|
238
325
|
|
326
|
+
##
|
327
|
+
# Hides y axis lines.
|
328
|
+
|
239
329
|
def hide_y
|
240
330
|
@y = Float::NAN
|
241
331
|
|
@@ -1,12 +1,19 @@
|
|
1
1
|
require_relative 'core'
|
2
2
|
|
3
3
|
module Rust::Plots
|
4
|
+
|
5
|
+
##
|
6
|
+
# Represents any distribution-related plot (e.g., boxplots).
|
7
|
+
|
4
8
|
class DistributionPlot < BasePlot
|
5
9
|
def initialize
|
6
10
|
super()
|
7
11
|
@series = []
|
8
12
|
end
|
9
13
|
|
14
|
+
##
|
15
|
+
# Adds a series of data points. +options+ can be specified and directly passed to the R plotting function.
|
16
|
+
|
10
17
|
def series(data, **options)
|
11
18
|
@series << [data, options]
|
12
19
|
|
@@ -14,6 +21,9 @@ module Rust::Plots
|
|
14
21
|
end
|
15
22
|
end
|
16
23
|
|
24
|
+
##
|
25
|
+
# Represents a density plot in R.
|
26
|
+
|
17
27
|
class DensityPlot < DistributionPlot
|
18
28
|
protected
|
19
29
|
def _show()
|
@@ -38,6 +48,9 @@ module Rust::Plots
|
|
38
48
|
end
|
39
49
|
end
|
40
50
|
|
51
|
+
##
|
52
|
+
# Represents a boxplot in R.
|
53
|
+
|
41
54
|
class BoxPlot < DistributionPlot
|
42
55
|
protected
|
43
56
|
def _show()
|
@@ -1,7 +1,18 @@
|
|
1
1
|
require_relative '../core'
|
2
2
|
|
3
|
+
##
|
4
|
+
# Module containing all the correlation-related statistics.
|
5
|
+
|
3
6
|
module Rust::Correlation
|
7
|
+
|
8
|
+
##
|
9
|
+
# Pearson correlation utility methods.
|
10
|
+
|
4
11
|
class Pearson
|
12
|
+
|
13
|
+
##
|
14
|
+
# Runs the Pearson correlation test between +d1+ and +d2+.
|
15
|
+
|
5
16
|
def self.test(d1, d2)
|
6
17
|
raise TypeError, "Expecting Array of numerics" if !d1.is_a?(Array) || !d1.all? { |e| e.is_a?(Numeric) }
|
7
18
|
raise TypeError, "Expecting Array of numerics" if !d2.is_a?(Array) || !d2.all? { |e| e.is_a?(Numeric) }
|
@@ -23,12 +34,22 @@ module Rust::Correlation
|
|
23
34
|
end
|
24
35
|
end
|
25
36
|
|
37
|
+
##
|
38
|
+
# Returns the Pearson correlation index between +d1+ and +d2+
|
39
|
+
|
26
40
|
def self.estimate(d1, d2)
|
27
41
|
self.test(d1, d2).correlation
|
28
42
|
end
|
29
43
|
end
|
30
44
|
|
45
|
+
##
|
46
|
+
# Spearman correlation utility methods.
|
47
|
+
|
31
48
|
class Spearman
|
49
|
+
|
50
|
+
##
|
51
|
+
# Runs the Spearman correlation test between +d1+ and +d2+.
|
52
|
+
|
32
53
|
def self.test(d1, d2)
|
33
54
|
raise TypeError, "Expecting Array of numerics" if !d1.is_a?(Array) || !d1.all? { |e| e.is_a?(Numeric) }
|
34
55
|
raise TypeError, "Expecting Array of numerics" if !d2.is_a?(Array) || !d2.all? { |e| e.is_a?(Numeric) }
|
@@ -50,12 +71,22 @@ module Rust::Correlation
|
|
50
71
|
end
|
51
72
|
end
|
52
73
|
|
74
|
+
##
|
75
|
+
# Returns the Spearman correlation index between +d1+ and +d2+
|
76
|
+
|
53
77
|
def self.estimate(d1, d2)
|
54
78
|
self.test(d1, d2).correlation
|
55
79
|
end
|
56
80
|
end
|
57
81
|
|
82
|
+
##
|
83
|
+
# Kendall correlation utility methods.
|
84
|
+
|
58
85
|
class Kendall
|
86
|
+
|
87
|
+
##
|
88
|
+
# Runs the Kendall correlation test between +d1+ and +d2+.
|
89
|
+
|
59
90
|
def self.test(d1, d2)
|
60
91
|
raise TypeError, "Expecting Array of numerics" if !d1.is_a?(Array) || !d1.all? { |e| e.is_a?(Numeric) }
|
61
92
|
raise TypeError, "Expecting Array of numerics" if !d2.is_a?(Array) || !d2.all? { |e| e.is_a?(Numeric) }
|
@@ -77,11 +108,17 @@ module Rust::Correlation
|
|
77
108
|
end
|
78
109
|
end
|
79
110
|
|
111
|
+
##
|
112
|
+
# Returns the Kendall correlation index between +d1+ and +d2+
|
113
|
+
|
80
114
|
def self.estimate(d1, d2)
|
81
115
|
self.test(d1, d2).correlation
|
82
116
|
end
|
83
117
|
end
|
84
118
|
|
119
|
+
##
|
120
|
+
# Result of a correlation test.
|
121
|
+
|
85
122
|
class Result
|
86
123
|
attr_accessor :name
|
87
124
|
attr_accessor :statistics
|
@@ -96,10 +133,16 @@ module Rust::Correlation
|
|
96
133
|
@exact = true
|
97
134
|
end
|
98
135
|
|
136
|
+
##
|
137
|
+
# Returns the statistic with the specified +name+.
|
138
|
+
|
99
139
|
def [](name)
|
100
140
|
return @statistics[name.to_sym]
|
101
141
|
end
|
102
142
|
|
143
|
+
##
|
144
|
+
# Sets the +value+ for the the statistic with the specified +name+.
|
145
|
+
|
103
146
|
def []=(name, value)
|
104
147
|
@statistics[name.to_sym] = value
|
105
148
|
end
|
@@ -1,13 +1,23 @@
|
|
1
1
|
require_relative '../core'
|
2
2
|
|
3
|
+
##
|
4
|
+
# Module containing utilities for descriptive statistics.
|
5
|
+
|
3
6
|
module Rust::Descriptive
|
4
7
|
class << self
|
8
|
+
|
9
|
+
##
|
10
|
+
# Computes the arithmetic mean of the given +data+.
|
11
|
+
|
5
12
|
def mean(data)
|
6
13
|
raise TypeError, "Expecting Array of numerics" if !data.is_a?(Array) || !data.all? { |e| e.is_a?(Numeric) }
|
7
14
|
|
8
15
|
return data.sum.to_f / data.size
|
9
16
|
end
|
10
17
|
|
18
|
+
##
|
19
|
+
# Computes the standard deviation of the given +data+.
|
20
|
+
|
11
21
|
def standard_deviation(data)
|
12
22
|
raise TypeError, "Expecting Array of numerics" if !data.is_a?(Array) || !data.all? { |e| e.is_a?(Numeric) }
|
13
23
|
|
@@ -16,6 +26,9 @@ module Rust::Descriptive
|
|
16
26
|
alias :sd :standard_deviation
|
17
27
|
alias :stddev :standard_deviation
|
18
28
|
|
29
|
+
##
|
30
|
+
# Computes the variance of the given +data+.
|
31
|
+
|
19
32
|
def variance(data)
|
20
33
|
raise TypeError, "Expecting Array of numerics" if !data.is_a?(Array) || !data.all? { |e| e.is_a?(Numeric) }
|
21
34
|
return Float::NAN if data.size < 2
|
@@ -25,6 +38,9 @@ module Rust::Descriptive
|
|
25
38
|
end
|
26
39
|
alias :var :variance
|
27
40
|
|
41
|
+
##
|
42
|
+
# Computes the median of the given +data+.
|
43
|
+
|
28
44
|
def median(data)
|
29
45
|
raise TypeError, "Expecting Array of numerics" if !data.is_a?(Array) || !data.all? { |e| e.is_a?(Numeric) }
|
30
46
|
|
@@ -39,12 +55,18 @@ module Rust::Descriptive
|
|
39
55
|
end
|
40
56
|
end
|
41
57
|
|
58
|
+
##
|
59
|
+
# Sums the given +data+.
|
60
|
+
|
42
61
|
def sum(data)
|
43
62
|
raise TypeError, "Expecting Array of numerics" if !data.is_a?(Array) || !data.all? { |e| e.is_a?(Numeric) }
|
44
63
|
|
45
64
|
return data.sum
|
46
65
|
end
|
47
66
|
|
67
|
+
##
|
68
|
+
# Returns the quantiles of the given +data+, given the +percentiles+ (optional).
|
69
|
+
|
48
70
|
def quantile(data, percentiles = [0.0, 0.25, 0.5, 0.75, 1.0])
|
49
71
|
raise TypeError, "Expecting Array of numerics" if !data.is_a?(Array) || !data.all? { |e| e.is_a?(Numeric) }
|
50
72
|
raise TypeError, "Expecting Array of numerics" if !percentiles.is_a?(Array) || !percentiles.all? { |e| e.is_a?(Numeric) }
|
@@ -77,10 +99,17 @@ module Rust::Descriptive
|
|
77
99
|
return percentiles.zip(result).to_h
|
78
100
|
end
|
79
101
|
|
102
|
+
##
|
103
|
+
# Returns the outliers in +data+ using Tukey's fences, with a given +k+.
|
104
|
+
|
80
105
|
def outliers(data, k=1.5, **opts)
|
81
106
|
outliers_according_to(data, data, k, **opts)
|
82
107
|
end
|
83
108
|
|
109
|
+
##
|
110
|
+
# Returns the outliers in +data+ using Tukey's fences, with a given +k+, with respect to different data
|
111
|
+
# distribution (+data_distribution+).
|
112
|
+
|
84
113
|
def outliers_according_to(data, data_distribution, k=1.5, **opts)
|
85
114
|
quantiles = Rust::Descriptive.quantile(data_distribution, [0.25, 0.75])
|
86
115
|
q1 = quantiles[0.25]
|
data/lib/rust/stats/effsize.rb
CHANGED
@@ -2,7 +2,14 @@ require_relative '../core'
|
|
2
2
|
|
3
3
|
Rust.prerequisite('effsize')
|
4
4
|
|
5
|
+
##
|
6
|
+
# Module containing utilities for computing effect size statistics.
|
7
|
+
|
5
8
|
module Rust::EffectSize
|
9
|
+
|
10
|
+
##
|
11
|
+
# Effect size results.
|
12
|
+
|
6
13
|
class Result
|
7
14
|
attr_accessor :name
|
8
15
|
attr_accessor :estimate
|
@@ -15,7 +22,14 @@ module Rust::EffectSize
|
|
15
22
|
end
|
16
23
|
end
|
17
24
|
|
25
|
+
##
|
26
|
+
# Cliff delta effect size statistics.
|
27
|
+
|
18
28
|
class CliffDelta
|
29
|
+
|
30
|
+
##
|
31
|
+
# Computes and returns the effect size for +d1+ and +d2+.
|
32
|
+
|
19
33
|
def self.compute(d1, d2)
|
20
34
|
raise TypeError, "Expecting Array of numerics" if !d1.is_a?(Array) || !d1.all? { |e| e.is_a?(Numeric) }
|
21
35
|
raise TypeError, "Expecting Array of numerics" if !d2.is_a?(Array) || !d2.all? { |e| e.is_a?(Numeric) }
|
@@ -42,7 +56,14 @@ module Rust::EffectSize
|
|
42
56
|
end
|
43
57
|
end
|
44
58
|
|
59
|
+
##
|
60
|
+
# Cohen D effect size statistics.
|
61
|
+
|
45
62
|
class CohenD
|
63
|
+
|
64
|
+
##
|
65
|
+
# Computes and returns the effect size for +d1+ and +d2+.
|
66
|
+
|
46
67
|
def self.compute(d1, d2)
|
47
68
|
raise TypeError, "Expecting Array of numerics" if !d1.is_a?(Array) || !d1.all? { |e| e.is_a?(Numeric) }
|
48
69
|
raise TypeError, "Expecting Array of numerics" if !d2.is_a?(Array) || !d2.all? { |e| e.is_a?(Numeric) }
|