red_amber 0.2.0 → 0.2.2

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +5 -0
  3. data/CHANGELOG.md +125 -0
  4. data/README.md +86 -269
  5. data/doc/DataFrame.md +427 -281
  6. data/doc/Vector.md +35 -54
  7. data/doc/image/basic_verbs.png +0 -0
  8. data/doc/image/dataframe/assign.png +0 -0
  9. data/doc/image/dataframe/assign_operation.png +0 -0
  10. data/doc/image/dataframe/drop.png +0 -0
  11. data/doc/image/dataframe/pick.png +0 -0
  12. data/doc/image/dataframe/pick_operation.png +0 -0
  13. data/doc/image/dataframe/remove.png +0 -0
  14. data/doc/image/dataframe/rename.png +0 -0
  15. data/doc/image/dataframe/rename_operation.png +0 -0
  16. data/doc/image/dataframe/reshaping_DataFrames.png +0 -0
  17. data/doc/image/dataframe/slice.png +0 -0
  18. data/doc/image/dataframe/slice_operation.png +0 -0
  19. data/doc/image/dataframe_model.png +0 -0
  20. data/doc/image/group_operation.png +0 -0
  21. data/doc/image/replace-if_then.png +0 -0
  22. data/doc/image/reshaping_dataframe.png +0 -0
  23. data/doc/image/screenshot.png +0 -0
  24. data/doc/image/vector/binary_element_wise.png +0 -0
  25. data/doc/image/vector/unary_aggregation.png +0 -0
  26. data/doc/image/vector/unary_aggregation_w_option.png +0 -0
  27. data/doc/image/vector/unary_element_wise.png +0 -0
  28. data/lib/red_amber/data_frame.rb +33 -41
  29. data/lib/red_amber/data_frame_displayable.rb +59 -6
  30. data/lib/red_amber/data_frame_loadsave.rb +36 -0
  31. data/lib/red_amber/data_frame_reshaping.rb +12 -10
  32. data/lib/red_amber/data_frame_selectable.rb +53 -9
  33. data/lib/red_amber/data_frame_variable_operation.rb +57 -20
  34. data/lib/red_amber/group.rb +5 -3
  35. data/lib/red_amber/helper.rb +20 -18
  36. data/lib/red_amber/vector.rb +50 -31
  37. data/lib/red_amber/vector_functions.rb +21 -24
  38. data/lib/red_amber/vector_selectable.rb +18 -9
  39. data/lib/red_amber/vector_updatable.rb +6 -3
  40. data/lib/red_amber/version.rb +1 -1
  41. data/lib/red_amber.rb +1 -0
  42. metadata +13 -3
  43. data/doc/examples_of_red_amber.ipynb +0 -6783
@@ -3,8 +3,8 @@
3
3
  module RedAmber
4
4
  # mix-in for the class DataFrame
5
5
  module DataFrameSelectable
6
- # select variables: [symbol] or [string]
7
- # select observations: [array of index], [range]
6
+ # select columns: [symbol] or [string]
7
+ # select rows: [array of index], [range]
8
8
  def [](*args)
9
9
  args.flatten!
10
10
  raise DataFrameArgumentError, 'Empty dataframe' if empty?
@@ -22,17 +22,17 @@ module RedAmber
22
22
  raise DataFrameArgumentError, "Invalid argument: #{args}"
23
23
  end
24
24
 
25
- # slice and select some observations to create sub DataFrame
25
+ # slice and select rows to create sub DataFrame
26
26
  def slice(*args, &block)
27
27
  slicer = args
28
28
  if block
29
29
  raise DataFrameArgumentError, 'Must not specify both arguments and block.' unless args.empty?
30
30
 
31
- slicer = instance_eval(&block)
31
+ slicer = [instance_eval(&block)]
32
32
  end
33
- slicer = [slicer].flatten
33
+ slicer.flatten!
34
34
 
35
- raise DataFrameArgumentError, 'Empty dataframe' if empty?
35
+ raise DataFrameArgumentError, 'Self is an empty dataframe' if empty?
36
36
  return remove_all_values if slicer.empty? || slicer[0].nil?
37
37
 
38
38
  vector = parse_to_vector(slicer)
@@ -46,15 +46,59 @@ module RedAmber
46
46
  raise DataFrameArgumentError, "Invalid argument #{slicer}"
47
47
  end
48
48
 
49
- # remove selected observations to create sub DataFrame
49
+ def slice_by(key, keep_key: false, &block)
50
+ raise DataFrameArgumentError, 'Self is an empty dataframe' if empty?
51
+ raise DataFrameArgumentError, 'No block given' unless block
52
+ raise DataFrameArgumentError, "#{key} is no a key of self" unless key?(key)
53
+ return self if key.nil?
54
+
55
+ slicer = instance_eval(&block)
56
+ return DataFrame.new unless slicer
57
+
58
+ if slicer.is_a?(Range)
59
+ from = slicer.begin
60
+ from =
61
+ if from.is_a?(String)
62
+ self[key].index(from)
63
+ elsif from.nil?
64
+ 0
65
+ elsif from < 0
66
+ size + from
67
+ else
68
+ from
69
+ end
70
+ to = slicer.end
71
+ to =
72
+ if to.is_a?(String)
73
+ self[key].index(to)
74
+ elsif to.nil?
75
+ size - 1
76
+ elsif to < 0
77
+ size + to
78
+ else
79
+ to
80
+ end
81
+ slicer = (from..to).to_a
82
+ else
83
+ slicer = slicer.map { |x| x.is_a?(String) ? self[key].index(x) : x }
84
+ end
85
+
86
+ if keep_key
87
+ take(slicer)
88
+ else
89
+ take(slicer).drop(key)
90
+ end
91
+ end
92
+
93
+ # remove selected rows to create remainer DataFrame
50
94
  def remove(*args, &block)
51
95
  remover = args
52
96
  if block
53
97
  raise DataFrameArgumentError, 'Must not specify both arguments and block.' unless args.empty?
54
98
 
55
- remover = instance_eval(&block)
99
+ remover = [instance_eval(&block)]
56
100
  end
57
- remover = [remover].flatten
101
+ remover.flatten!
58
102
 
59
103
  raise DataFrameArgumentError, 'Empty dataframe' if empty?
60
104
  return self if remover.empty? || remover[0].nil?
@@ -9,18 +9,28 @@ module RedAmber
9
9
  if block
10
10
  raise DataFrameArgumentError, 'Must not specify both arguments and block.' unless args.empty?
11
11
 
12
- picker = instance_eval(&block)
12
+ picker = [instance_eval(&block)]
13
13
  end
14
- picker = [picker].flatten
14
+ picker.flatten!
15
15
  return DataFrame.new if picker.empty? || picker == [nil]
16
16
 
17
- picker = keys_by_booleans(picker) if booleans?(picker)
17
+ key_vector = Vector.new(keys)
18
+ vec = parse_to_vector(picker, vsize: n_keys)
19
+
20
+ ary =
21
+ if vec.boolean?
22
+ key_vector.filter(*vec).to_a
23
+ elsif vec.numeric?
24
+ key_vector.take(*vec).to_a
25
+ elsif vec.string? || vec.dictionary?
26
+ picker
27
+ else
28
+ raise DataFrameArgumentError, "Invalid argument #{args}"
29
+ end
18
30
 
19
31
  # DataFrame#[] creates a Vector with single key is specified.
20
32
  # DataFrame#pick creates a DataFrame with single key.
21
- return DataFrame.new(@table[picker]) if sym_or_str?(picker)
22
-
23
- raise DataFrameArgumentError, "Invalid argument #{args}"
33
+ DataFrame.new(@table[ary])
24
34
  end
25
35
 
26
36
  # drop some variables to create remainer sub DataFrame
@@ -29,19 +39,29 @@ module RedAmber
29
39
  if block
30
40
  raise DataFrameArgumentError, 'Must not specify both arguments and block.' unless args.empty?
31
41
 
32
- dropper = instance_eval(&block)
42
+ dropper = [instance_eval(&block)]
33
43
  end
34
- dropper = [dropper].flatten
35
- dropper = keys_by_booleans(dropper) if booleans?(dropper)
44
+ dropper.flatten!
45
+
46
+ key_vector = Vector.new(keys)
47
+ vec = parse_to_vector(dropper, vsize: n_keys)
48
+
49
+ ary =
50
+ if vec.boolean?
51
+ key_vector.filter(*vec.primitive_invert).each.map(&:to_sym) # Array
52
+ elsif vec.numeric?
53
+ keys - key_vector.take(*vec).each.map(&:to_sym) # Array
54
+ elsif vec.string? || vec.dictionary?
55
+ keys - dropper
56
+ else
57
+ raise DataFrameArgumentError, "Invalid argument #{args}"
58
+ end
36
59
 
37
- picker = keys - dropper
38
- return DataFrame.new if picker.empty?
60
+ return DataFrame.new if ary.empty?
39
61
 
40
62
  # DataFrame#[] creates a Vector with single key is specified.
41
63
  # DataFrame#drop creates a DataFrame with single key.
42
- return DataFrame.new(@table[picker]) if sym_or_str?(picker)
43
-
44
- raise DataFrameArgumentError, "Invalid argument #{args}"
64
+ DataFrame.new(@table[ary])
45
65
  end
46
66
 
47
67
  # rename variables to create a new DataFrame
@@ -91,10 +111,20 @@ module RedAmber
91
111
 
92
112
  def assign_update(*assigner, &block)
93
113
  if block
94
- raise DataFrameArgumentError, 'Must not specify both arguments and a block' unless assigner.empty?
95
-
96
- assigner = [instance_eval(&block)]
114
+ assigner_from_block = instance_eval(&block)
115
+ assigner =
116
+ if assigner.empty?
117
+ # block only
118
+ [assigner_from_block]
119
+ # If Ruby >= 3.0, one line pattern match can be used
120
+ # assigner_from_block in [Array, *]
121
+ elsif multiple_assigner?(assigner_from_block)
122
+ assigner.zip(assigner_from_block)
123
+ else
124
+ assigner.zip([assigner_from_block])
125
+ end
97
126
  end
127
+
98
128
  case assigner
99
129
  in [] | [nil] | [{}] | [[]]
100
130
  return self
@@ -113,6 +143,8 @@ module RedAmber
113
143
  updater = {}
114
144
  appender = {}
115
145
  key_array_pairs.each do |key, array|
146
+ raise DataFrameArgumentError, "Empty column data: #{key} => nil" if array.nil?
147
+
116
148
  if keys.include? key
117
149
  updater[key] = array
118
150
  else
@@ -153,7 +185,7 @@ module RedAmber
153
185
  data = updater[key]
154
186
  next unless data
155
187
 
156
- raise DataFrameArgumentError, "Data size mismatch (#{data.size} != #{size})" if data.size != size
188
+ raise DataFrameArgumentError, "Data size mismatch (#{data.size} != #{size})" if data.nil? || data.size != size
157
189
 
158
190
  a = Arrow::Array.new(data.is_a?(Vector) ? data.to_a : data)
159
191
  fields[i] = Arrow::Field.new(key, a.value_data_type)
@@ -179,8 +211,13 @@ module RedAmber
179
211
  end
180
212
  end
181
213
 
182
- def keys_by_booleans(booleans)
183
- keys.select.with_index { |_, i| booleans[i] }
214
+ def multiple_assigner?(assigner)
215
+ case assigner
216
+ in [Vector, *] | [Array, *] | [Arrow::Array, *]
217
+ true
218
+ else
219
+ false
220
+ end
184
221
  end
185
222
  end
186
223
  end
@@ -54,9 +54,11 @@ module RedAmber
54
54
  raise GroupArgumentError, "#{d} is not a key of\n #{@dataframe}." unless summary_keys.empty? || d.empty?
55
55
 
56
56
  df = RedAmber::DataFrame.new(@group.send(func, *summary_keys))
57
- df = df[@group_keys, df.keys - @group_keys]
58
- # if counts are the same (no nil included), aggregate count columns.
59
- df = df[df.keys[0..1]].rename(df.keys[1], :count) if func == :count && df.to_h.values[1..].uniq.size == 1
57
+ df = df.pick(@group_keys, df.keys - @group_keys)
58
+ # if counts are the same (and do not include NaN or nil), aggregate count columns.
59
+ if func == :count && df.pick(@group_keys.size..).to_h.values.uniq.size == 1
60
+ df = df.pick(0..@group_keys.size).rename { [keys[-1], :count] }
61
+ end
60
62
  df
61
63
  end
62
64
  end
@@ -17,10 +17,6 @@ module RedAmber
17
17
  enum.all?(Integer)
18
18
  end
19
19
 
20
- def sym_or_str?(enum)
21
- enum.all? { |e| e.is_a?(Symbol) || e.is_a?(String) }
22
- end
23
-
24
20
  def booleans?(enum)
25
21
  enum.all? { |e| e.is_a?(TrueClass) || e.is_a?(FalseClass) || e.is_a?(NilClass) }
26
22
  end
@@ -29,32 +25,38 @@ module RedAmber
29
25
  DataFrame.new(key => vector.data)
30
26
  end
31
27
 
32
- def parse_to_vector(args)
28
+ def parse_to_vector(args, vsize: size)
33
29
  a = args.reduce([]) do |accum, elem|
34
- accum.concat(normalize_element(elem))
30
+ accum.concat(normalize_element(elem, vsize: vsize))
35
31
  end
36
32
  Vector.new(a)
37
33
  end
38
34
 
39
- def normalize_element(elem)
35
+ def normalize_element(elem, vsize: size)
40
36
  case elem
41
- when Numeric, String, Symbol, TrueClass, FalseClass, NilClass
42
- [elem]
37
+ when NilClass
38
+ [nil]
43
39
  when Range
44
- both_end = [elem.begin, elem.end]
45
- both_end[1] -= 1 if elem.exclude_end? && elem.end.is_a?(Integer)
46
-
47
- if both_end.any?(Integer) || both_end.all?(&:nil?)
48
- if both_end.any? { |e| e&.>=(size) || e&.<(-size) }
49
- raise DataFrameArgumentError, "Index out of range: #{elem} for 0..#{size - 1}"
40
+ bg = elem.begin
41
+ en = elem.end
42
+ if [bg, en].any?(Integer)
43
+ bg += vsize if bg&.negative?
44
+ en += vsize if en&.negative?
45
+ en -= 1 if en.is_a?(Integer) && elem.exclude_end?
46
+ if bg&.negative? || (en && en >= vsize)
47
+ raise DataFrameArgumentError, "Index out of range: #{elem} for 0..#{vsize - 1}"
50
48
  end
51
49
 
52
- (0...size).to_a[elem]
50
+ Array(0...vsize)[elem]
51
+ elsif bg.nil? && en.nil?
52
+ Array(0...vsize)
53
53
  else
54
- elem.to_a
54
+ Array[elem]
55
55
  end
56
+ when Enumerator
57
+ elem.to_a
56
58
  else
57
- Array(elem)
59
+ Array[elem]
58
60
  end
59
61
  end
60
62
  end
@@ -11,27 +11,28 @@ module RedAmber
11
11
  include Helper
12
12
 
13
13
  def initialize(*array)
14
- @key = nil # default is 'headless'
15
- if array.empty? || array[0].nil?
14
+ @key = nil # default is 'headless' Vector
15
+ if array.empty? || array.first.nil?
16
16
  Vector.new([])
17
17
  else
18
18
  array.flatten!
19
- case array[0]
20
- when Vector
21
- @data = array[0].data
22
- return
23
- when Arrow::Array, Arrow::ChunkedArray
24
- @data = array[0]
25
- return
26
- when Range
27
- @data = Arrow::Array.new(Array(array[0]))
28
- return
29
- end
30
- begin
31
- @data = Arrow::Array.new(Array(array))
32
- rescue Error
33
- raise VectorArgumentError, "Invalid argument: #{array}"
34
- end
19
+ @data =
20
+ case array
21
+ in [Vector => v]
22
+ v.data
23
+ in [Arrow::Array => a]
24
+ a
25
+ in [Arrow::ChunkedArray => ca]
26
+ ca
27
+ in [Range => r]
28
+ Arrow::Array.new(Array(r))
29
+ else
30
+ begin
31
+ Arrow::Array.new(Array(array))
32
+ rescue Error
33
+ raise VectorArgumentError, "Invalid argument: #{array}"
34
+ end
35
+ end
35
36
  end
36
37
  end
37
38
 
@@ -43,19 +44,24 @@ module RedAmber
43
44
  end
44
45
 
45
46
  def inspect(limit: 80)
46
- sio = StringIO.new << '['
47
- to_a.each_with_object(sio).with_index do |(e, s), i|
48
- next_str = "#{s.size > 1 ? ', ' : ''}#{e.inspect}"
49
- if (s.size + next_str.size) < limit
50
- s << next_str
51
- else
52
- s << ', ... ' if i < size
53
- break
47
+ if ENV.fetch('RED_AMBER_OUTPUT_MODE', 'Table').casecmp('MINIMUM').zero?
48
+ # Better performance than `.upcase == 'MINIMUM'``
49
+ "#{self.class}(:#{type}, size=#{size})"
50
+ else
51
+ sio = StringIO.new << '['
52
+ to_a.each_with_object(sio).with_index do |(e, s), i|
53
+ next_str = "#{s.size > 1 ? ', ' : ''}#{e.inspect}"
54
+ if (s.size + next_str.size) < limit
55
+ s << next_str
56
+ else
57
+ s << ', ... ' if i < size
58
+ break
59
+ end
54
60
  end
55
- end
56
- sio << ']'
61
+ sio << ']'
57
62
 
58
- format "#<#{self.class}(:#{type}, size=#{size}):0x%016x>\n%s\n", object_id, sio.string
63
+ format "#<#{self.class}(:#{type}, size=#{size}):0x%016x>\n%s\n", object_id, sio.string
64
+ end
59
65
  end
60
66
 
61
67
  def values
@@ -71,7 +77,7 @@ module RedAmber
71
77
  alias_method :indeces, :indices
72
78
 
73
79
  def to_ary
74
- to_a
80
+ values
75
81
  end
76
82
 
77
83
  def size
@@ -110,6 +116,10 @@ module RedAmber
110
116
  type_class == Arrow::StringDataType
111
117
  end
112
118
 
119
+ def dictionary?
120
+ type_class == Arrow::DictionaryDataType
121
+ end
122
+
113
123
  def temporal?
114
124
  type_class < Arrow::TemporalDataType
115
125
  end
@@ -122,14 +132,23 @@ module RedAmber
122
132
  return enum_for(:each) unless block_given?
123
133
 
124
134
  size.times do |i|
125
- yield self[i]
135
+ yield data[i]
126
136
  end
127
137
  end
128
138
 
139
+ def map(&block)
140
+ return enum_for(:map) unless block
141
+
142
+ Vector.new(to_a.map(&block))
143
+ end
144
+ alias_method :collect, :map
145
+
146
+ # undocumented
129
147
  def chunked?
130
148
  @data.is_a? Arrow::ChunkedArray
131
149
  end
132
150
 
151
+ # undocumented
133
152
  def n_chunks
134
153
  chunked? ? @data.n_chunks : 0
135
154
  end
@@ -34,13 +34,6 @@ module RedAmber
34
34
  end
35
35
  alias_method :std, :sd
36
36
 
37
- # option(s) required
38
- # - index
39
-
40
- # Returns other than value
41
- # - mode
42
- # - tdigest
43
-
44
37
  # Return quantile
45
38
  # 0.5 quantile (median) is returned by default.
46
39
  # Or return quantile for specified probability (prob).
@@ -88,8 +81,9 @@ module RedAmber
88
81
 
89
82
  # [Unary element-wise]: vector.func => vector
90
83
  unary_element_wise =
91
- %i[abs array_sort_indices atan bit_wise_not ceil cos fill_null_backward fill_null_forward floor is_finite
92
- is_inf is_nan is_null is_valid round round_to_multiple sign sin tan trunc unique]
84
+ %i[abs acos asin array_sort_indices atan bit_wise_not ceil cos fill_null_backward \
85
+ fill_null_forward floor is_finite is_inf is_nan is_null is_valid ln log10 log1p log2 \
86
+ round round_to_multiple sign sin tan trunc unique]
93
87
  unary_element_wise.each do |function|
94
88
  define_method(function) do |**options|
95
89
  datum = exec_func_unary(function, options)
@@ -129,16 +123,9 @@ module RedAmber
129
123
  end
130
124
  alias_method :not, :invert
131
125
 
132
- # NaN support needed
133
- # - acos asin ln log10 log1p log2
134
-
135
- # Functions with numerical range check
136
- # - abs_checked acos_checked asin_checked cos_checked ln_checked
137
- # log10_checked log1p_checked log2_checked sin_checked tan_checked
138
-
139
126
  # [Binary element-wise]: vector.func(other) => vector
140
127
  binary_element_wise =
141
- %i[atan2 and_not and_not_kleene bit_wise_and bit_wise_or bit_wise_xor]
128
+ %i[atan2 and_not and_not_kleene bit_wise_and bit_wise_or bit_wise_xor logb]
142
129
  binary_element_wise.each do |function|
143
130
  define_method(function) do |other, **options|
144
131
  datum = exec_func_binary(function, other, options)
@@ -162,13 +149,6 @@ module RedAmber
162
149
  end
163
150
  end
164
151
 
165
- # NaN support needed
166
- # - logb
167
-
168
- # Functions with numerical range check
169
- # - add_checked divide_checked logb_checked multiply_checked power_checked subtract_checked
170
- # shift_left_checked shift_right_checked
171
-
172
152
  # [Binary element-wise with operator]: vector.func(other) => vector
173
153
  binary_element_wise_op = {
174
154
  add: '+',
@@ -216,6 +196,23 @@ module RedAmber
216
196
  [Vector.new(Array(other) * size), self]
217
197
  end
218
198
 
199
+ # < Not implimented yet > ---
200
+
201
+ # option(s) required
202
+ # - index
203
+
204
+ # Returns other than value
205
+ # - mode
206
+ # - tdigest
207
+
208
+ # Functions with numerical range check (unary)
209
+ # - abs_checked acos_checked asin_checked cos_checked ln_checked
210
+ # log10_checked log1p_checked log2_checked sin_checked tan_checked
211
+
212
+ # Functions with numerical range check (binary)
213
+ # - add_checked divide_checked logb_checked multiply_checked power_checked subtract_checked
214
+ # shift_left_checked shift_right_checked
215
+
219
216
  # (array functions)
220
217
  # dictionary_encode,
221
218
  # partition_nth_indices,
@@ -25,7 +25,13 @@ module RedAmber
25
25
  end
26
26
 
27
27
  # TODO: support for option {null_selection_behavior: :drop}
28
- def filter(*booleans)
28
+ def filter(*booleans, &block)
29
+ if block
30
+ raise VectorArgumentError, 'Must not specify both arguments and block.' unless booleans.empty?
31
+
32
+ booleans = [yield]
33
+ end
34
+
29
35
  booleans.flatten!
30
36
  return Vector.new([]) if booleans.empty?
31
37
 
@@ -46,6 +52,8 @@ module RedAmber
46
52
 
47
53
  filter_by_array(boolean_array) # returns sub Vector
48
54
  end
55
+ alias_method :select, :filter
56
+ alias_method :find_all, :filter
49
57
 
50
58
  # @param indices
51
59
  # @param booleans
@@ -82,16 +90,17 @@ module RedAmber
82
90
 
83
91
  # @param values [Array, Arrow::Array, Vector]
84
92
  def is_in(*values)
85
- values.flatten!
93
+ self_data = chunked? ? data.pack : data
94
+
86
95
  array =
87
- case values[0]
88
- when Vector
89
- values[0].data
90
- when Arrow::Array
91
- values[0]
96
+ case values
97
+ in [Vector] | [Arrow::Array] | [Arrow::ChunkedArray]
98
+ values[0].to_a
99
+ else
100
+ Array(values).flatten
92
101
  end
93
- array ||= data.class.new(values)
94
- Vector.new(data.is_in(array))
102
+
103
+ Vector.new(self_data.is_in(array))
95
104
  end
96
105
 
97
106
  # Arrow's support required
@@ -8,9 +8,10 @@ module RedAmber
8
8
  # Functions to make up some data (especially missing) for new data.
9
9
  module VectorUpdatable
10
10
  # Replace data
11
- # @param arg [Array, Vector, Arrow::Array] index specifier
11
+ # @param arg [Array, Vector, Arrow::Array] index specifier or boolean
12
12
  # @param replacer [Array, Vector, Arrow::Array] new data to replace for.
13
- # @return [Vector] Replaced new Vector
13
+ # @return [Vector] Replaced new Vector.
14
+ # If arg has no true, return self.
14
15
  def replace(args, replacer)
15
16
  args =
16
17
  case args
@@ -24,10 +25,12 @@ module RedAmber
24
25
  replacer = Array(replacer)
25
26
  return self if args.empty? || args[0].nil?
26
27
 
27
- replacer = nil if replacer.empty?
28
28
  vector = parse_to_vector(args)
29
+ replacer = nil if replacer.empty?
29
30
  booleans =
30
31
  if vector.boolean?
32
+ return self unless vector.any
33
+
31
34
  vector
32
35
  elsif vector.numeric?
33
36
  replacer.sort_by! { |x| args[replacer.index(x)] } if replacer # rubocop:disable Style/SafeNavigation
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RedAmber
4
- VERSION = '0.2.0'
4
+ VERSION = '0.2.2'
5
5
  end
data/lib/red_amber.rb CHANGED
@@ -5,6 +5,7 @@ require 'arrow'
5
5
  require_relative 'red_amber/helper'
6
6
  require_relative 'red_amber/data_frame_displayable'
7
7
  require_relative 'red_amber/data_frame_indexable'
8
+ require_relative 'red_amber/data_frame_loadsave'
8
9
  require_relative 'red_amber/data_frame_reshaping'
9
10
  require_relative 'red_amber/data_frame_selectable'
10
11
  require_relative 'red_amber/data_frame_variable_operation'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: red_amber
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hirokazu SUZUKI (heronshoes)
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-08-15 00:00:00.000000000 Z
11
+ date: 2022-10-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: red-arrow
@@ -45,16 +45,25 @@ files:
45
45
  - doc/CODE_OF_CONDUCT.md
46
46
  - doc/DataFrame.md
47
47
  - doc/Vector.md
48
- - doc/examples_of_red_amber.ipynb
49
48
  - doc/image/arrow_table_new.png
49
+ - doc/image/basic_verbs.png
50
50
  - doc/image/dataframe/assign.png
51
+ - doc/image/dataframe/assign_operation.png
51
52
  - doc/image/dataframe/drop.png
52
53
  - doc/image/dataframe/pick.png
54
+ - doc/image/dataframe/pick_operation.png
53
55
  - doc/image/dataframe/remove.png
54
56
  - doc/image/dataframe/rename.png
57
+ - doc/image/dataframe/rename_operation.png
58
+ - doc/image/dataframe/reshaping_DataFrames.png
55
59
  - doc/image/dataframe/slice.png
60
+ - doc/image/dataframe/slice_operation.png
56
61
  - doc/image/dataframe_model.png
57
62
  - doc/image/example_in_red_arrow.png
63
+ - doc/image/group_operation.png
64
+ - doc/image/replace-if_then.png
65
+ - doc/image/reshaping_dataframe.png
66
+ - doc/image/screenshot.png
58
67
  - doc/image/tdr.png
59
68
  - doc/image/tdr_and_table.png
60
69
  - doc/image/tidy_data_in_TDR.png
@@ -69,6 +78,7 @@ files:
69
78
  - lib/red_amber/data_frame.rb
70
79
  - lib/red_amber/data_frame_displayable.rb
71
80
  - lib/red_amber/data_frame_indexable.rb
81
+ - lib/red_amber/data_frame_loadsave.rb
72
82
  - lib/red_amber/data_frame_reshaping.rb
73
83
  - lib/red_amber/data_frame_selectable.rb
74
84
  - lib/red_amber/data_frame_variable_operation.rb