rust 0.9 → 0.12

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.
@@ -1,6 +1,10 @@
1
1
  require_relative 'datatype'
2
2
 
3
3
  module Rust
4
+
5
+ ##
6
+ # Mirror of the factor type in R.
7
+
4
8
  class Factor < RustDatatype
5
9
  def self.can_pull?(type, klass)
6
10
  return klass == "factor"
@@ -20,11 +24,17 @@ module Rust
20
24
  Rust._eval("#{variable_name} <- factor(tmp.values, labels=tmp.levels)")
21
25
  end
22
26
 
27
+ ##
28
+ # Creates a new factor given an array of numeric +values+ and symbolic +levels+.
29
+
23
30
  def initialize(values, levels)
24
31
  @levels = levels.map { |v| v.to_sym }
25
32
  @values = values
26
33
  end
27
34
 
35
+ ##
36
+ # Returns the levels of the factor.
37
+
28
38
  def levels
29
39
  @levels
30
40
  end
@@ -35,10 +45,17 @@ module Rust
35
45
  return @levels == other.levels && self.to_a == other.to_a
36
46
  end
37
47
 
48
+ ##
49
+ # Returns the value of the +i+-th element in the factor.
50
+
38
51
  def [](i)
39
52
  FactorValue.new(@values[i], @levels[@values[i] - 1])
40
53
  end
41
54
 
55
+ ##
56
+ # Sets the +value+ of the +i+-th element in the factor. If it is an Integer, the +value+ must be between 1 and
57
+ # the number of levels of the factor. +value+ can be either a FactorValue or a String/Symbol.
58
+
42
59
  def []=(i, value)
43
60
  raise "The given value is outside the factor bounds" if value.is_a?(Integer) && (value < 1 || value > @levels.size)
44
61
 
@@ -57,6 +74,9 @@ module Rust
57
74
  @values[i] = value
58
75
  end
59
76
 
77
+ ##
78
+ # Returns an array of FactorValue for the values in this factor.
79
+
60
80
  def to_a
61
81
  @values.map { |v| FactorValue.new(v, @levels[v - 1]) }
62
82
  end
@@ -76,7 +96,14 @@ module Rust
76
96
  end
77
97
  end
78
98
 
99
+ ##
100
+ # Represents a single value in a factor.
101
+
79
102
  class FactorValue
103
+
104
+ ##
105
+ # Creates a factor with a given +value+ (numeric) and +level+ (symbolic).
106
+
80
107
  def initialize(value, level)
81
108
  @value = value
82
109
  @level = level
@@ -1,6 +1,10 @@
1
1
  require_relative 'datatype'
2
2
 
3
3
  module Rust
4
+
5
+ ##
6
+ # Mirror of the formula type in R.
7
+
4
8
  class Formula < RustDatatype
5
9
  def self.can_pull?(type, klass)
6
10
  return klass == "formula" || (klass.is_a?(Array) && klass.include?("formula"))
@@ -24,6 +28,9 @@ module Rust
24
28
  attr_reader :left_part
25
29
  attr_reader :right_part
26
30
 
31
+ ##
32
+ # Creates a new formula with a given +left_part+ (optional) and +right_part+ (as strings).
33
+
27
34
  def initialize(left_part, right_part)
28
35
  raise ArgumentError, "Expected string" if left_part && !left_part.is_a?(String)
29
36
  raise ArgumentError, "Expected string" if !right_part.is_a?(String)
@@ -46,7 +53,10 @@ module Rust
46
53
  return self.to_R.strip
47
54
  end
48
55
  end
49
-
56
+
57
+ ##
58
+ # Mirror of the call type in R.
59
+
50
60
  class Call < RustDatatype
51
61
  def self.can_pull?(type, klass)
52
62
  return klass == "call"
@@ -61,6 +71,9 @@ module Rust
61
71
  Rust._eval("#{variable_name} <- str2lang(call.str)")
62
72
  end
63
73
 
74
+ ##
75
+ # Creates a new call with the given +value+ (String).
76
+
64
77
  def initialize(value)
65
78
  @value = value
66
79
  end
@@ -74,6 +87,9 @@ module Rust
74
87
  end
75
88
  end
76
89
 
90
+ ##
91
+ # Mirror of the environment type in R. Currently not supported.
92
+
77
93
  class Environment < RustDatatype
78
94
  def self.can_pull?(type, klass)
79
95
  return type == "environment" && klass == "environment"
@@ -90,25 +106,38 @@ module Rust
90
106
  end
91
107
  end
92
108
 
109
+ ##
110
+ # Represents a function call in R. After having set up its name (constructor) and, optionally, its arguments
111
+ # and options, it can be used the call method to execute it in the R environment.
112
+
93
113
  class Function
94
114
  attr_reader :name
95
115
  attr_reader :arguments
96
116
  attr_reader :options
97
117
 
118
+ ##
119
+ # Creates a new function with a given +name+.
120
+
98
121
  def initialize(name)
99
122
  @function = name
100
123
  @arguments = Arguments.new
101
124
  @options = Options.new
102
125
  end
103
126
 
127
+ ##
128
+ # Sets the +options+ (Options type) of the function.
129
+
104
130
  def options=(options)
105
131
  raise TypeError, "Expected Options" unless options.is_a?(Options)
106
132
 
107
133
  @options = options
108
134
  end
109
135
 
136
+ ##
137
+ # Sets the +arguments+ (Arguments type) of the function.
138
+
110
139
  def arguments=(arguments)
111
- raise TypeError, "Expected Arguments" unless options.is_a?(Arguments)
140
+ raise TypeError, "Expected Arguments" unless arguments.is_a?(Arguments)
112
141
 
113
142
  @arguments = arguments
114
143
  end
@@ -118,23 +147,21 @@ module Rust
118
147
  return "#@function(#{params})"
119
148
  end
120
149
 
150
+ ##
151
+ # Calls the function in the R environment.
152
+
121
153
  def call
122
154
  Rust._eval(self.to_R)
123
155
  end
124
156
  end
125
157
 
126
- class SimpleFormula
127
- def initialize(dependent, independent)
128
- @dependent = dependent
129
- @independent = independent
130
- end
131
-
132
- def to_R
133
- return "#@dependent ~ #@independent"
134
- end
135
- end
158
+ ##
159
+ # Represents an R variable.
136
160
 
137
161
  class Variable
162
+ ##
163
+ # Creates a variable with the given +name+.
164
+
138
165
  def initialize(name)
139
166
  @name = name
140
167
  end
@@ -144,12 +171,18 @@ module Rust
144
171
  end
145
172
  end
146
173
 
174
+ ##
175
+ # Represents the arguments of a function in R. Works as an Array of objects.
176
+
147
177
  class Arguments < Array
148
178
  def to_R
149
179
  return self.map { |v| v.to_R }.join(", ")
150
180
  end
151
181
  end
152
182
 
183
+ ##
184
+ # Represents the options of a function in R. Works as a Hash associating option names to objects.
185
+
153
186
  class Options < Hash
154
187
  def to_R
155
188
  return self.map { |k, v| "#{k}=#{v.to_R}" }.join(", ")
@@ -1,6 +1,10 @@
1
1
  require_relative 'datatype'
2
2
 
3
3
  module Rust
4
+
5
+ ##
6
+ # Mirror of the list type in R.
7
+
4
8
  class List < RustDatatype
5
9
  def self.can_pull?(type, klass)
6
10
  return type == "list"
@@ -27,12 +31,18 @@ module Rust
27
31
  end
28
32
  end
29
33
 
34
+ ##
35
+ # Creates an empty list of a given class (+klass+) and the specified +names+.
36
+
30
37
  def initialize(klass, names = [])
31
38
  @data = {}
32
39
  @names = names
33
40
  @klass = klass
34
41
  end
35
42
 
43
+ ##
44
+ # Returns the elements for the name +key+.
45
+
36
46
  def [](key)
37
47
  key = get_key(key)
38
48
 
@@ -40,12 +50,18 @@ module Rust
40
50
  end
41
51
  alias :| :[]
42
52
 
53
+ ##
54
+ # Sets the +value+ for name +key+.
55
+
43
56
  def []=(key, value)
44
57
  key = get_key(key)
45
58
 
46
59
  return @data[key] = value
47
60
  end
48
61
 
62
+ ##
63
+ # Returns the names of the list.
64
+
49
65
  def names
50
66
  @names
51
67
  end
@@ -1,6 +1,10 @@
1
1
  require_relative 'datatype'
2
2
 
3
3
  module Rust
4
+
5
+ ##
6
+ # Mirror of the matrix type in R.
7
+
4
8
  class Matrix < RustDatatype
5
9
  def self.can_pull?(type, klass)
6
10
  return klass.is_a?(Array) && klass.include?("matrix")
@@ -27,6 +31,10 @@ module Rust
27
31
  Rust[variable_name] = matrix
28
32
  end
29
33
 
34
+ ##
35
+ # Creates a new matrix with the given +data+ (Ruby Matrix). Optionally, +row_names+ and +column_names+ can
36
+ # be specified.
37
+
30
38
  def initialize(data, row_names = nil, column_names = nil)
31
39
  @data = data.clone
32
40
 
@@ -48,30 +56,45 @@ module Rust
48
56
  end
49
57
  end
50
58
 
59
+ ##
60
+ # Returns the matrix element at row +i+ and column +j+.
61
+
51
62
  def [](i, j)
52
63
  i, j = indices(i, j)
53
64
 
54
65
  return @data[i][j]
55
66
  end
56
67
 
68
+ ##
69
+ # Sets the matrix element at row +i+ and column +j+ with +value+.
70
+
71
+ def []=(i, j, value)
72
+ i, j = indices(i, j)
73
+
74
+ @data[i][j] = value
75
+ end
76
+
77
+ ##
78
+ # Returns the number of rows.
79
+
57
80
  def rows
58
81
  @data.size
59
82
  end
60
83
 
84
+ ##
85
+ # Returns the number of columns.
86
+
61
87
  def cols
62
88
  @data[0].size
63
89
  end
64
90
 
91
+ ##
92
+ # Returns a flattened version of the matrix (Array).
93
+
65
94
  def flatten
66
95
  return @data.flatten
67
96
  end
68
97
 
69
- def []=(i, j, value)
70
- i, j = indices(i, j)
71
-
72
- @data[i][j] = value
73
- end
74
-
75
98
  def inspect
76
99
  row_names = @row_names || (0...self.rows).to_a.map { |v| v.to_s }
77
100
  column_names = @column_names || (0...self.cols).to_a.map { |v| v.to_s }
@@ -1,6 +1,10 @@
1
1
  require_relative 'datatype'
2
2
 
3
3
  module Rust
4
+
5
+ ##
6
+ # Mirror for the S4 class in R.
7
+
4
8
  class S4Class < RustDatatype
5
9
  def self.can_pull?(type, klass)
6
10
  return type == "S4"
@@ -20,6 +24,9 @@ module Rust
20
24
  "immutable"
21
25
  end
22
26
 
27
+ ##
28
+ # Creates a new S4 element, given its +variable_name+, class name (+klass+), and +slots+.
29
+
23
30
  def initialize(variable_name, klass, slots)
24
31
  @klass = klass
25
32
  @slots = slots
@@ -27,6 +34,9 @@ module Rust
27
34
  self.r_mirror_to(variable_name)
28
35
  end
29
36
 
37
+ ##
38
+ # Returns the slot +key+ for the class name (+klass+).
39
+
30
40
  def [](key)
31
41
  raise ArgumentError, "Unknown slot `#{key}` for class `#@klass`" unless @slots.include?(key)
32
42
 
@@ -36,6 +46,9 @@ module Rust
36
46
  end
37
47
  alias :| :[]
38
48
 
49
+ ##
50
+ # Returns the slot +key+ for the class name (+klass+) with +value+.
51
+
39
52
  def []=(key, value)
40
53
  raise ArgumentError, "Unknown slot `#{key}` for class `#@klass`" unless @slots.include?(key)
41
54
 
@@ -44,10 +57,16 @@ module Rust
44
57
  end
45
58
  end
46
59
 
60
+ ##
61
+ # Returns the slots.
62
+
47
63
  def slots
48
64
  @slots
49
65
  end
50
66
 
67
+ ##
68
+ # Returns the class name.
69
+
51
70
  def class_name
52
71
  @klass
53
72
  end
@@ -1,6 +1,10 @@
1
1
  require_relative 'datatype'
2
2
 
3
3
  module Rust
4
+
5
+ ##
6
+ # Represents a sequence of values in R (through a call to the seq function).
7
+
4
8
  class Sequence < RustDatatype
5
9
  attr_reader :min
6
10
  attr_reader :max
@@ -9,15 +13,24 @@ module Rust
9
13
  return false
10
14
  end
11
15
 
16
+ ##
17
+ # Creates a new sequence from +min+ to +max+ with a given +step+ (default = 1).
18
+
12
19
  def initialize(min, max, step=1)
13
20
  @min = min
14
21
  @max = max
15
22
  @step = step
16
23
  end
17
24
 
18
- def step(step)
25
+ ##
26
+ # Sets the step to +step+.
27
+
28
+ def step=(step)
19
29
  @step = step
30
+
31
+ return self
20
32
  end
33
+ alias :step :step=
21
34
 
22
35
  def each
23
36
  (@min..@max).step(@step) do |v|
@@ -0,0 +1,171 @@
1
+ require_relative '../../../rust'
2
+
3
+ Rust.prerequisite("ggplot2")
4
+
5
+ module Rust::Plots::GGPlot
6
+ def self.default_theme
7
+ @@theme
8
+ end
9
+
10
+ def self.default_theme=(theme)
11
+ @@theme = theme.freeze
12
+ end
13
+
14
+ class Layer
15
+ def initialize(function_name, **options)
16
+ @function_name = function_name
17
+ @arguments = Rust::Arguments.new
18
+ @options = Rust::Options.from_hash(options)
19
+ end
20
+
21
+ def option(key, value)
22
+ @options[key] = value
23
+ end
24
+
25
+ def to_R
26
+ if !block_given?
27
+ options, arguments = @options, @arguments
28
+ else
29
+ options, arguments = yield(@options, @arguments)
30
+ end
31
+
32
+ options = Rust::Options.from_hash(options) unless options.is_a?(Rust::Options)
33
+
34
+ function = Rust::Function.new(@function_name)
35
+ function.arguments = arguments if arguments
36
+ function.options = options if options
37
+ return function.to_R
38
+ end
39
+ end
40
+
41
+ class Aes
42
+ def initialize(**options)
43
+ options = options.map { |k, v| [k, v.is_a?(Symbol) ? Rust::Variable.new(v) : v] }.to_h
44
+ @options = Rust::Options.from_hash(options)
45
+ end
46
+
47
+ def to_R
48
+ function = Rust::Function.new("aes")
49
+ function.options = @options if @options
50
+ return function.to_R
51
+ end
52
+ end
53
+
54
+ class Plot
55
+ attr_accessor :theme
56
+ attr_accessor :aes
57
+
58
+ def initialize(data, aes = nil)
59
+ @layers = []
60
+
61
+ @data = data
62
+ @aes = aes
63
+ @theme = Rust::Plots::GGPlot.default_theme
64
+ end
65
+
66
+ def layer(layer)
67
+ @layers << layer
68
+ end
69
+
70
+ def show()
71
+ Rust.exclusive do
72
+ dataset_name = nil
73
+ if @data
74
+ dataset_name = "ggplotter.data"
75
+ @data.load_in_r_as(dataset_name)
76
+ end
77
+ r = self.to_R(dataset_name)
78
+ Rust._eval(r)
79
+ end
80
+ end
81
+
82
+ def save(filename, **options)
83
+ Rust.exclusive do
84
+ dataset_name = nil
85
+ if @data
86
+ dataset_name = "ggplotter.data"
87
+ @data.load_in_r_as(dataset_name)
88
+ end
89
+ r = self.to_R(dataset_name)
90
+ Rust._eval("ggplot.latest <- #{r}")
91
+ save = Rust::Function.new("ggsave")
92
+ save.arguments = Rust::Arguments.new([Rust::Variable.new("ggplot.latest")])
93
+ save.options = Rust::Options.from_hash({file: filename}.merge(options))
94
+ save.call
95
+ end
96
+ end
97
+
98
+ def to_R(data_set_name="ggplotter.data")
99
+ function = Rust::Function.new("ggplot")
100
+ function.arguments = Rust::Arguments.new
101
+ function.arguments << (data_set_name ? Rust::Variable.new(data_set_name) : nil)
102
+ function.arguments << @aes if @aes
103
+
104
+ result = function.to_R
105
+ result += " + " + @theme.to_R
106
+ @layers.each do |layer|
107
+ result += " + " + layer.to_R
108
+ end
109
+
110
+ return result
111
+ end
112
+
113
+ def <<(others)
114
+ if others.is_a?(Array) && others.all? { |o| o.is_a?(Layer) }
115
+ @layers += others
116
+ elsif others.is_a?(Layer)
117
+ @layers << others
118
+ else
119
+ raise ArgumentError, "Expected Layer or Array of Layers"
120
+ end
121
+
122
+ return self
123
+ end
124
+
125
+ def +(others)
126
+ copy = self.deep_clone
127
+ copy << others
128
+ return copy
129
+ end
130
+
131
+ def inspect(show = true)
132
+ self.show if show
133
+ return super()
134
+ end
135
+ end
136
+
137
+ class Labels < Layer
138
+ def initialize(**options)
139
+ super("labs", **options)
140
+ end
141
+ end
142
+
143
+ class FlipCoordinates < Layer
144
+ def initialize(**options)
145
+ super("coord_flip", **options)
146
+ end
147
+ end
148
+ end
149
+
150
+ module Rust::RBindings
151
+ def ggplot(*arguments)
152
+ Rust::Plots::GGPlot::Plot.new(*arguments)
153
+ end
154
+
155
+ def aes(**options)
156
+ Rust::Plots::GGPlot::Aes.new(**options)
157
+ end
158
+
159
+ def labs(**options)
160
+ Rust::Plots::GGPlot::Labels.new(**options)
161
+ end
162
+ alias :labels :labs
163
+
164
+ def coord_flip(**options)
165
+ Rust::Plots::GGPlot::FlipCoordinates.new(**options)
166
+ end
167
+ end
168
+
169
+ def bind_ggplot!
170
+ include Rust::Plots::GGPlot
171
+ end
@@ -0,0 +1,83 @@
1
+ require_relative 'core'
2
+
3
+ module Rust::Plots::GGPlot
4
+ class Geom < Layer
5
+ def initialize(type, arguments = [], **options)
6
+ super("geom_#{type}", **options)
7
+ @type = type
8
+ @arguments = Rust::Arguments.new(arguments)
9
+ end
10
+ end
11
+
12
+ class GeomPoint < Geom
13
+ def initialize(arguments = [], **options)
14
+ super("point", arguments, **options)
15
+ end
16
+ end
17
+
18
+ class GeomLine < Geom
19
+ def initialize(arguments = [], **options)
20
+ super("line", arguments, **options)
21
+ end
22
+ end
23
+
24
+ class GeomCol < Geom
25
+ def initialize(arguments = [], **options)
26
+ super("col", arguments, **options)
27
+ end
28
+ end
29
+
30
+ class GeomBoxplot < Geom
31
+ def initialize(arguments = [], **options)
32
+ super("boxplot", arguments, **options)
33
+ end
34
+ end
35
+
36
+ class GeomBar < Geom
37
+ def initialize(arguments = [], **options)
38
+ super("bar", arguments, **options)
39
+ end
40
+ end
41
+
42
+ class GeomHistogram < Geom
43
+ def initialize(arguments = [], **options)
44
+ super("histogram", arguments, **options)
45
+ end
46
+ end
47
+
48
+ class GeomDensity < Geom
49
+ def initialize(arguments = [], **options)
50
+ super("density", arguments, **options)
51
+ end
52
+ end
53
+ end
54
+
55
+ module Rust::RBindings
56
+ def geom_point(*arguments, **options)
57
+ return Rust::Plots::GGPlot::GeomPoint.new(*arguments, **options)
58
+ end
59
+
60
+ def geom_line(*arguments, **options)
61
+ return Rust::Plots::GGPlot::GeomLine.new(*arguments, **options)
62
+ end
63
+
64
+ def geom_col(*arguments, **options)
65
+ return Rust::Plots::GGPlot::GeomCol.new(*arguments, **options)
66
+ end
67
+
68
+ def geom_bar(*arguments, **options)
69
+ return Rust::Plots::GGPlot::GeomBar.new(*arguments, **options)
70
+ end
71
+
72
+ def geom_boxplot(*arguments, **options)
73
+ return Rust::Plots::GGPlot::GeomBoxplot.new(*arguments, **options)
74
+ end
75
+
76
+ def geom_histogram(*arguments, **options)
77
+ return Rust::Plots::GGPlot::GeomHistogram.new(*arguments, **options)
78
+ end
79
+
80
+ def geom_density(*arguments, **options)
81
+ return Rust::Plots::GGPlot::GeomDensity.new(*arguments, **options)
82
+ end
83
+ end