daru_lite 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +35 -33
  3. data/lib/daru_lite/data_frame/aggregatable.rb +165 -0
  4. data/lib/daru_lite/data_frame/calculatable.rb +140 -0
  5. data/lib/daru_lite/data_frame/convertible.rb +107 -0
  6. data/lib/daru_lite/data_frame/duplicatable.rb +64 -0
  7. data/lib/daru_lite/data_frame/fetchable.rb +301 -0
  8. data/lib/daru_lite/data_frame/filterable.rb +144 -0
  9. data/lib/daru_lite/data_frame/i_o_able.rb +179 -0
  10. data/lib/daru_lite/data_frame/indexable.rb +168 -0
  11. data/lib/daru_lite/data_frame/iterable.rb +339 -0
  12. data/lib/daru_lite/data_frame/joinable.rb +152 -0
  13. data/lib/daru_lite/data_frame/missable.rb +75 -0
  14. data/lib/daru_lite/data_frame/pivotable.rb +108 -0
  15. data/lib/daru_lite/data_frame/queryable.rb +67 -0
  16. data/lib/daru_lite/data_frame/setable.rb +109 -0
  17. data/lib/daru_lite/data_frame/sortable.rb +241 -0
  18. data/lib/daru_lite/dataframe.rb +138 -2353
  19. data/lib/daru_lite/index/index.rb +14 -1
  20. data/lib/daru_lite/index/multi_index.rb +9 -0
  21. data/lib/daru_lite/maths/statistics/vector.rb +1 -1
  22. data/lib/daru_lite/vector/aggregatable.rb +9 -0
  23. data/lib/daru_lite/vector/calculatable.rb +78 -0
  24. data/lib/daru_lite/vector/convertible.rb +77 -0
  25. data/lib/daru_lite/vector/duplicatable.rb +17 -0
  26. data/lib/daru_lite/vector/fetchable.rb +175 -0
  27. data/lib/daru_lite/vector/filterable.rb +128 -0
  28. data/lib/daru_lite/vector/indexable.rb +77 -0
  29. data/lib/daru_lite/vector/iterable.rb +95 -0
  30. data/lib/daru_lite/vector/joinable.rb +17 -0
  31. data/lib/daru_lite/vector/missable.rb +124 -0
  32. data/lib/daru_lite/vector/queryable.rb +45 -0
  33. data/lib/daru_lite/vector/setable.rb +47 -0
  34. data/lib/daru_lite/vector/sortable.rb +113 -0
  35. data/lib/daru_lite/vector.rb +36 -932
  36. data/lib/daru_lite/version.rb +1 -1
  37. data/spec/data_frame/aggregatable_example.rb +65 -0
  38. data/spec/data_frame/buildable_example.rb +109 -0
  39. data/spec/data_frame/calculatable_example.rb +135 -0
  40. data/spec/data_frame/convertible_example.rb +180 -0
  41. data/spec/data_frame/duplicatable_example.rb +111 -0
  42. data/spec/data_frame/fetchable_example.rb +476 -0
  43. data/spec/data_frame/filterable_example.rb +409 -0
  44. data/spec/data_frame/indexable_example.rb +221 -0
  45. data/spec/data_frame/iterable_example.rb +465 -0
  46. data/spec/data_frame/joinable_example.rb +106 -0
  47. data/spec/data_frame/missable_example.rb +47 -0
  48. data/spec/data_frame/pivotable_example.rb +297 -0
  49. data/spec/data_frame/queryable_example.rb +92 -0
  50. data/spec/data_frame/setable_example.rb +482 -0
  51. data/spec/data_frame/sortable_example.rb +350 -0
  52. data/spec/dataframe_spec.rb +181 -3289
  53. data/spec/index/categorical_index_spec.rb +27 -8
  54. data/spec/index/index_spec.rb +21 -0
  55. data/spec/index/multi_index_spec.rb +85 -76
  56. data/spec/vector/aggregatable_example.rb +27 -0
  57. data/spec/vector/calculatable_example.rb +82 -0
  58. data/spec/vector/convertible_example.rb +126 -0
  59. data/spec/vector/duplicatable_example.rb +48 -0
  60. data/spec/vector/fetchable_example.rb +463 -0
  61. data/spec/vector/filterable_example.rb +165 -0
  62. data/spec/vector/indexable_example.rb +201 -0
  63. data/spec/vector/iterable_example.rb +111 -0
  64. data/spec/vector/joinable_example.rb +25 -0
  65. data/spec/vector/missable_example.rb +88 -0
  66. data/spec/vector/queryable_example.rb +91 -0
  67. data/spec/vector/setable_example.rb +300 -0
  68. data/spec/vector/sortable_example.rb +242 -0
  69. data/spec/vector_spec.rb +111 -1805
  70. metadata +86 -2
@@ -1,36 +1,47 @@
1
1
  require 'spec_helper.rb'
2
2
 
3
3
  describe DaruLite::CategoricalIndex do
4
+ let(:index) { described_class.new(keys) }
5
+ let(:keys) { [:a, :b, :a, :a, :c] }
6
+
7
+ describe "#to_a" do
8
+ subject { index.to_a }
9
+
10
+ it { is_expected.to eq(keys) }
11
+
12
+ it 'the returns array is not a variable of the index' do
13
+ expect { subject << 'four' }.not_to change { index.to_a }
14
+ end
15
+ end
16
+
4
17
  context "#pos" do
5
18
  context "when the category is non-numeric" do
6
- let(:idx) { described_class.new [:a, :b, :a, :a, :c] }
7
-
8
19
  context "single category" do
9
- subject { idx.pos :a }
20
+ subject { index.pos :a }
10
21
 
11
22
  it { is_expected.to eq [0, 2, 3] }
12
23
  end
13
24
 
14
25
  context "multiple categories" do
15
- subject { idx.pos :a, :c }
26
+ subject { index.pos :a, :c }
16
27
 
17
28
  it { is_expected.to eq [0, 2, 3, 4] }
18
29
  end
19
30
 
20
31
  context "invalid category" do
21
- it { expect { idx.pos :e }.to raise_error IndexError }
32
+ it { expect { index.pos :e }.to raise_error IndexError }
22
33
  end
23
34
 
24
35
  context "positional index" do
25
- it { expect(idx.pos 0).to eq 0 }
36
+ it { expect(index.pos 0).to eq 0 }
26
37
  end
27
38
 
28
39
  context "invalid positional index" do
29
- it { expect { idx.pos 5 }.to raise_error IndexError }
40
+ it { expect { index.pos 5 }.to raise_error IndexError }
30
41
  end
31
42
 
32
43
  context "multiple positional indexes" do
33
- subject { idx.pos 0, 1, 2 }
44
+ subject { index.pos 0, 1, 2 }
34
45
 
35
46
  it { is_expected.to be_a Array }
36
47
  its(:size) { is_expected.to eq 3 }
@@ -167,4 +178,12 @@ describe DaruLite::CategoricalIndex do
167
178
  it { expect(idx.valid? :a, 1, 5).to eq false }
168
179
  end
169
180
  end
181
+
182
+ describe '#delete_at' do
183
+ subject { index.delete_at(3) }
184
+
185
+ let(:index) { described_class.new([:a, 1, :a, 1, 'c']) }
186
+
187
+ it { is_expected.to eq(described_class.new([:a, 1, :a, 'c'])) }
188
+ end
170
189
  end
@@ -1,6 +1,9 @@
1
1
  require 'spec_helper.rb'
2
2
 
3
3
  describe DaruLite::Index do
4
+ let(:index) { described_class.new(keys) }
5
+ let(:keys) { ['one', 'two', 'three'] }
6
+
4
7
  context ".new" do
5
8
  it "creates an Index object if Index-like data is supplied" do
6
9
  i = DaruLite::Index.new [:one, 'one', 1, 2, :two]
@@ -147,6 +150,16 @@ describe DaruLite::Index do
147
150
  end
148
151
  end
149
152
 
153
+ describe "#to_a" do
154
+ subject { index.to_a }
155
+
156
+ it { is_expected.to eq(keys) }
157
+
158
+ it 'the returns array is not a variable of the index' do
159
+ expect { subject << 'four' }.not_to change { index.to_a }
160
+ end
161
+ end
162
+
150
163
  context "#&" do
151
164
  before :each do
152
165
  @left = DaruLite::Index.new [:miles, :geddy, :eric]
@@ -389,6 +402,14 @@ describe DaruLite::Index do
389
402
 
390
403
  end
391
404
 
405
+ describe '#delete_at' do
406
+ subject { index.delete_at(1) }
407
+
408
+ let(:index) { described_class.new([:a, :b, 1, 2]) }
409
+
410
+ it { is_expected.to eq(described_class.new([:a, 1, 2])) }
411
+ end
412
+
392
413
  context '#to_df' do
393
414
  let(:idx) do
394
415
  DaruLite::Index.new(['speaker', 'mic', 'guitar', 'amp'],
@@ -1,22 +1,22 @@
1
1
  require 'spec_helper.rb'
2
2
 
3
3
  describe DaruLite::MultiIndex do
4
- before(:each) do
5
- @index_tuples = [
6
- [:a,:one,:bar],
7
- [:a,:one,:baz],
8
- [:a,:two,:bar],
9
- [:a,:two,:baz],
10
- [:b,:one,:bar],
11
- [:b,:two,:bar],
12
- [:b,:two,:baz],
13
- [:b,:one,:foo],
14
- [:c,:one,:bar],
15
- [:c,:one,:baz],
16
- [:c,:two,:foo],
17
- [:c,:two,:bar]
4
+ let(:index) { described_class.from_tuples(index_tuples) }
5
+ let(:index_tuples) do
6
+ [
7
+ [:a, :one, :bar],
8
+ [:a, :one, :baz],
9
+ [:a, :two, :bar],
10
+ [:a, :two, :baz],
11
+ [:b, :one, :bar],
12
+ [:b, :two, :bar],
13
+ [:b, :two, :baz],
14
+ [:b, :one, :foo],
15
+ [:c, :one, :bar],
16
+ [:c, :one, :baz],
17
+ [:c, :two, :foo],
18
+ [:c, :two, :bar]
18
19
  ]
19
- @multi_mi = DaruLite::MultiIndex.from_tuples(@index_tuples)
20
20
  end
21
21
 
22
22
  context ".initialize" do
@@ -71,16 +71,16 @@ describe DaruLite::MultiIndex do
71
71
 
72
72
  it "raises SizeError for wrong number of name" do
73
73
  error_msg = "\'names\' and \'levels\' should be of same size. Size of the \'name\' array is 2 and size of the MultiIndex \'levels\' and \'labels\' is 3.\nIf you do not want to set name for particular level (say level \'i\') then put empty string on index \'i\' of the \'name\' Array."
74
- expect { @multi_mi.name = ['n1', 'n2'] }.to raise_error(SizeError, error_msg)
74
+ expect { index.name = ['n1', 'n2'] }.to raise_error(SizeError, error_msg)
75
75
 
76
76
  error_msg = "'names' and 'levels' should be of same size. Size of the 'name' array is 0 and size of the MultiIndex 'levels' and 'labels' is 3.\nIf you do not want to set name for particular level (say level 'i') then put empty string on index 'i' of the 'name' Array."
77
- expect { @multi_mi.name = [ ] }.to raise_error(SizeError, error_msg)
77
+ expect { index.name = [ ] }.to raise_error(SizeError, error_msg)
78
78
 
79
79
  error_msg = "'names' and 'levels' should be of same size. Size of the 'name' array is 1 and size of the MultiIndex 'levels' and 'labels' is 3.\nIf you do not want to set name for particular level (say level 'i') then put empty string on index 'i' of the 'name' Array."
80
- expect { @multi_mi.name = [''] }.to raise_error(SizeError, error_msg)
80
+ expect { index.name = [''] }.to raise_error(SizeError, error_msg)
81
81
 
82
82
  error_msg = "'names' and 'levels' should be of same size. Size of the 'name' array is 4 and size of the MultiIndex 'levels' and 'labels' is 3."
83
- expect { @multi_mi.name = ['n1', 'n2', 'n3', 'n4'] }.to raise_error(SizeError, error_msg)
83
+ expect { index.name = ['n1', 'n2', 'n3', 'n4'] }.to raise_error(SizeError, error_msg)
84
84
  end
85
85
  end
86
86
  end
@@ -101,8 +101,8 @@ describe DaruLite::MultiIndex do
101
101
  end
102
102
 
103
103
  it "creates a triple layer MultiIndex from tuples" do
104
- expect(@multi_mi.levels).to eq([[:a,:b,:c], [:one, :two],[:bar,:baz,:foo]])
105
- expect(@multi_mi.labels).to eq([
104
+ expect(index.levels).to eq([[:a,:b,:c], [:one, :two],[:bar,:baz,:foo]])
105
+ expect(index.labels).to eq([
106
106
  [0,0,0,0,1,1,1,1,2,2,2,2],
107
107
  [0,0,1,1,0,1,1,0,0,0,1,1],
108
108
  [0,1,0,1,0,0,1,2,0,1,2,0]
@@ -132,23 +132,23 @@ describe DaruLite::MultiIndex do
132
132
 
133
133
  context "#size" do
134
134
  it "returns size of MultiIndex" do
135
- expect(@multi_mi.size).to eq(12)
135
+ expect(index.size).to eq(12)
136
136
  end
137
137
  end
138
138
 
139
139
  context "#[]" do
140
140
  it "returns the row number when specifying the complete tuple" do
141
- expect(@multi_mi[:a, :one, :baz]).to eq(1)
141
+ expect(index[:a, :one, :baz]).to eq(1)
142
142
  end
143
143
 
144
144
  it "returns MultiIndex when specifying incomplete tuple" do
145
- expect(@multi_mi[:b]).to eq(DaruLite::MultiIndex.from_tuples([
145
+ expect(index[:b]).to eq(DaruLite::MultiIndex.from_tuples([
146
146
  [:b,:one,:bar],
147
147
  [:b,:two,:bar],
148
148
  [:b,:two,:baz],
149
149
  [:b,:one,:foo]
150
150
  ]))
151
- expect(@multi_mi[:b, :one]).to eq(DaruLite::MultiIndex.from_tuples([
151
+ expect(index[:b, :one]).to eq(DaruLite::MultiIndex.from_tuples([
152
152
  [:b,:one,:bar],
153
153
  [:b,:one,:foo]
154
154
  ]))
@@ -156,7 +156,7 @@ describe DaruLite::MultiIndex do
156
156
  end
157
157
 
158
158
  it "returns MultiIndex when specifying wholly numeric ranges" do
159
- expect(@multi_mi[3..6]).to eq(DaruLite::MultiIndex.from_tuples([
159
+ expect(index[3..6]).to eq(DaruLite::MultiIndex.from_tuples([
160
160
  [:a,:two,:baz],
161
161
  [:b,:one,:bar],
162
162
  [:b,:two,:bar],
@@ -165,11 +165,11 @@ describe DaruLite::MultiIndex do
165
165
  end
166
166
 
167
167
  it "raises error when specifying invalid index" do
168
- expect { @multi_mi[:a, :three] }.to raise_error IndexError
169
- expect { @multi_mi[:a, :one, :xyz] }.to raise_error IndexError
170
- expect { @multi_mi[:x] }.to raise_error IndexError
171
- expect { @multi_mi[:x, :one] }.to raise_error IndexError
172
- expect { @multi_mi[:x, :one, :bar] }.to raise_error IndexError
168
+ expect { index[:a, :three] }.to raise_error IndexError
169
+ expect { index[:a, :one, :xyz] }.to raise_error IndexError
170
+ expect { index[:x] }.to raise_error IndexError
171
+ expect { index[:x, :one] }.to raise_error IndexError
172
+ expect { index[:x, :one, :bar] }.to raise_error IndexError
173
173
  end
174
174
 
175
175
  it "works with numerical first levels" do
@@ -189,93 +189,89 @@ describe DaruLite::MultiIndex do
189
189
  end
190
190
  end
191
191
 
192
+ describe "#to_a" do
193
+ subject { index.to_a }
194
+
195
+ it { is_expected.to eq(index_tuples) }
196
+
197
+ it 'the returns array is not a variable of the index' do
198
+ expect { subject << [:d, :one, :bar] }.not_to change { index.to_a }
199
+ end
200
+ end
201
+
192
202
  context "#include?" do
193
203
  it "checks if a completely specified tuple exists" do
194
- expect(@multi_mi.include?([:a,:one,:bar])).to eq(true)
204
+ expect(index.include?([:a,:one,:bar])).to eq(true)
195
205
  end
196
206
 
197
207
  it "checks if a top layer incomplete tuple exists" do
198
- expect(@multi_mi.include?([:a])).to eq(true)
208
+ expect(index.include?([:a])).to eq(true)
199
209
  end
200
210
 
201
211
  it "checks if a middle layer incomplete tuple exists" do
202
- expect(@multi_mi.include?([:a, :one])).to eq(true)
212
+ expect(index.include?([:a, :one])).to eq(true)
203
213
  end
204
214
 
205
215
  it "checks for non-existence of completely specified tuple" do
206
- expect(@multi_mi.include?([:b, :two, :foo])).to eq(false)
216
+ expect(index.include?([:b, :two, :foo])).to eq(false)
207
217
  end
208
218
 
209
219
  it "checks for non-existence of a top layer incomplete tuple" do
210
- expect(@multi_mi.include?([:d])).to eq(false)
220
+ expect(index.include?([:d])).to eq(false)
211
221
  end
212
222
 
213
223
  it "checks for non-existence of a middle layer incomplete tuple" do
214
- expect(@multi_mi.include?([:c, :three])).to eq(false)
224
+ expect(index.include?([:c, :three])).to eq(false)
215
225
  end
216
226
  end
217
227
 
218
228
  context "#key" do
219
229
  it "returns the tuple of the specified number" do
220
- expect(@multi_mi.key(3)).to eq([:a,:two,:baz])
230
+ expect(index.key(3)).to eq([:a,:two,:baz])
221
231
  end
222
232
 
223
233
  it "returns nil for non-existent pointer number" do
224
234
  expect {
225
- @multi_mi.key(100)
235
+ index.key(100)
226
236
  }.to raise_error ArgumentError
227
237
  end
228
238
  end
229
239
 
230
240
  context "#to_a" do
231
241
  it "returns tuples as an Array" do
232
- expect(@multi_mi.to_a).to eq(@index_tuples)
242
+ expect(index.to_a).to eq(index_tuples)
233
243
  end
234
244
  end
235
245
 
236
246
  context "#dup" do
237
247
  it "completely duplicates the object" do
238
- duplicate = @multi_mi.dup
239
- expect(duplicate) .to eq(@multi_mi)
240
- expect(duplicate.object_id).to_not eq(@multi_mi.object_id)
248
+ duplicate = index.dup
249
+ expect(duplicate) .to eq(index)
250
+ expect(duplicate.object_id).to_not eq(index.object_id)
241
251
  end
242
252
  end
243
253
 
244
254
  context "#inspect" do
245
255
  context 'small index' do
246
- subject {
247
- DaruLite::MultiIndex.from_tuples [
248
- [:a,:one,:bar],
249
- [:a,:one,:baz],
250
- [:a,:two,:bar],
251
- [:a,:two,:baz],
252
- [:b,:one,:bar],
253
- [:b,:two,:bar],
254
- [:b,:two,:baz],
255
- [:b,:one,:foo],
256
- [:c,:one,:bar],
257
- [:c,:one,:baz],
258
- [:c,:two,:foo],
259
- [:c,:two,:bar]
260
- ]
261
- }
262
-
263
- its(:inspect) { is_expected.to eq %Q{
264
- |#<DaruLite::MultiIndex(12x3)>
265
- | a one bar
266
- | baz
267
- | two bar
268
- | baz
269
- | b one bar
270
- | two bar
271
- | baz
272
- | one foo
273
- | c one bar
274
- | baz
275
- | two foo
276
- | bar
256
+ subject { index.inspect }
257
+
258
+ it do
259
+ is_expected.to eq %Q{
260
+ |#<DaruLite::MultiIndex(12x3)>
261
+ | a one bar
262
+ | baz
263
+ | two bar
264
+ | baz
265
+ | b one bar
266
+ | two bar
267
+ | baz
268
+ | one foo
269
+ | c one bar
270
+ | baz
271
+ | two foo
272
+ | bar
277
273
  }.unindent
278
- }
274
+ end
279
275
  end
280
276
 
281
277
  context 'large index' do
@@ -331,7 +327,7 @@ describe DaruLite::MultiIndex do
331
327
 
332
328
  context 'multi index with name having empty string' do
333
329
  subject {
334
- mi= DaruLite::MultiIndex.new(
330
+ DaruLite::MultiIndex.new(
335
331
  levels: [[:a,:b,:c],[:one,:two],[:bar, :baz, :foo]],
336
332
  labels: [
337
333
  [0,0,0,0,1,1,1,1,2,2,2,2],
@@ -677,4 +673,17 @@ describe DaruLite::MultiIndex do
677
673
  'col3' => %w[bar bar baz foo]
678
674
  )}
679
675
  end
676
+
677
+ describe '#delete_at' do
678
+ subject { index.delete_at(3)}
679
+
680
+ let(:index) do
681
+ DaruLite::MultiIndex.from_tuples([[:a, :one], [:a, :two], [:b, :one], [:b, :two], [:c, :one]])
682
+ end
683
+ let(:expected_index) do
684
+ DaruLite::MultiIndex.from_tuples([[:a, :one], [:a, :two], [:b, :one], [:c, :one]])
685
+ end
686
+
687
+ it { is_expected.to eq(expected_index) }
688
+ end
680
689
  end
@@ -0,0 +1,27 @@
1
+ shared_examples_for 'an aggregatable Vector' do
2
+ context "#group_by" do
3
+ let(:dv) { DaruLite::Vector.new [:a, :b, :a, :b, :c] }
4
+
5
+ context 'vector not specified' do
6
+ subject { dv.group_by }
7
+
8
+ it { is_expected.to be_a DaruLite::Core::GroupBy }
9
+ its(:'groups.size') { is_expected.to eq 3 }
10
+ its(:groups) { is_expected.to eq({[:a]=>[0, 2], [:b]=>[1, 3], [:c]=>[4]}) }
11
+ end
12
+
13
+ context 'vector name specified' do
14
+ before { dv.name = :hello }
15
+ subject { dv.group_by :hello }
16
+
17
+ it { is_expected.to be_a DaruLite::Core::GroupBy }
18
+ its(:'groups.size') { is_expected.to eq 3 }
19
+ its(:groups) { is_expected.to eq({[:a]=>[0, 2], [:b]=>[1, 3], [:c]=>[4]}) }
20
+ end
21
+
22
+ context 'vector name invalid' do
23
+ before { dv.name = :hello }
24
+ it { expect { dv.group_by :abc }.to raise_error }
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,82 @@
1
+ shared_examples_for 'a calculatable Vector' do |dtype|
2
+ describe '#count_values' do
3
+ let(:vector) { DaruLite::Vector.new([1, 2, 3, 1, 2, nil, nil]) }
4
+
5
+ it { expect(vector.count_values 1, 2).to eq 4 }
6
+ it { expect(vector.count_values nil).to eq 2 }
7
+ it { expect(vector.count_values 3, Float::NAN).to eq 1 }
8
+ it { expect(vector.count_values 4).to eq 0 }
9
+ end
10
+
11
+ context "#summary" do
12
+ subject { vector.summary }
13
+
14
+ context 'all types' do
15
+ let(:vector) { DaruLite::Vector.new([1 ,2, 3, 4, 5], name: 'vector') }
16
+
17
+ it { is_expected.to include vector.name }
18
+
19
+ it { is_expected.to include "n :#{vector.size}" }
20
+
21
+ it { is_expected.to include "non-missing:#{vector.size - vector.count_values(*DaruLite::MISSING_VALUES)}" }
22
+ end
23
+
24
+
25
+ context "numeric type" do
26
+ let(:vector) { DaruLite::Vector.new([1,2,5], name: 'numeric') }
27
+
28
+ it { is_expected. to eq %Q{
29
+ |= numeric
30
+ | n :3
31
+ | non-missing:3
32
+ | median: 2
33
+ | mean: 2.6667
34
+ | std.dev.: 2.0817
35
+ | std.err.: 1.2019
36
+ | skew: 0.2874
37
+ | kurtosis: -2.3333
38
+ }.unindent }
39
+ end
40
+
41
+ context "numeric type with missing values" do
42
+ let(:vector) { DaruLite::Vector.new([1,2,5,nil,Float::NAN], name: 'numeric') }
43
+
44
+ it { is_expected.not_to include 'skew' }
45
+ it { is_expected.not_to include 'kurtosis' }
46
+ end
47
+
48
+ if dtype == :array
49
+ context "object type" do
50
+ let(:vector) { DaruLite::Vector.new([1, 1, 2, 2, "string", nil, Float::NAN], name: 'object') }
51
+
52
+ if RUBY_VERSION >= '2.2'
53
+ it { is_expected.to eq %Q{
54
+ |= object
55
+ | n :7
56
+ | non-missing:5
57
+ | factors: 1,2,string
58
+ | mode: 1,2
59
+ | Distribution
60
+ | string 1 50.00%
61
+ | NaN 1 50.00%
62
+ | 1 2 100.00%
63
+ | 2 2 100.00%
64
+ }.unindent }
65
+ else
66
+ it { is_expected.to eq %Q{
67
+ |= object
68
+ | n :7
69
+ | non-missing:5
70
+ | factors: 1,2,string
71
+ | mode: 1,2
72
+ | Distribution
73
+ | NaN 1 50.00%
74
+ | string 1 50.00%
75
+ | 2 2 100.00%
76
+ | 1 2 100.00%
77
+ }.unindent }
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,126 @@
1
+ shared_examples_for 'a convertible Vector' do |dtype|
2
+ describe "#to_df" do
3
+ subject { vector.to_df }
4
+
5
+ let(:vector) do
6
+ DaruLite::Vector.new(['a','b','c'], name: :my_dv, index: ['alpha', 'beta', 'gamma'])
7
+ end
8
+
9
+ it 'is a dataframe' do
10
+ expect(subject).to be_a DaruLite::DataFrame
11
+ end
12
+
13
+ it 'converts the vector to a single-vector dataframe' do
14
+ expect(subject[:my_dv]).to eq vector
15
+ end
16
+
17
+ it 'has the same index as the original vector' do
18
+ expect(subject.index).to eq vector.index
19
+ end
20
+
21
+ it 'has the same name as the vector' do
22
+ expect(subject.name).to eq :my_dv
23
+ end
24
+ end
25
+
26
+ describe "#to_h" do
27
+ context DaruLite::Index do
28
+ subject { vector.to_h }
29
+
30
+ let(:vector) do
31
+ DaruLite::Vector.new(
32
+ [1,2,3,4,5],
33
+ name: :a,
34
+ index: [:one, :two, :three, :four, :five],
35
+ dtype:
36
+ )
37
+ end
38
+
39
+ it "returns the vector as a hash" do
40
+ expect(subject).to eq({one: 1, two: 2, three: 3, four: 4, five: 5})
41
+ end
42
+ end
43
+
44
+ context DaruLite::MultiIndex do
45
+ pending
46
+ # it "returns vector as a Hash" do
47
+ # pending
48
+ # mi = DaruLite::MultiIndex.from_tuples([
49
+ # [:a,:two,:bar],
50
+ # [:a,:two,:baz],
51
+ # [:b,:one,:bar],
52
+ # [:b,:two,:bar]
53
+ # ])
54
+ # vector = DaruLite::Vector.new([1,2,3,4], index: mi, dtype: dtype)
55
+ # expect(vector.to_h).to eq({
56
+ # [:a,:two,:bar] => 1,
57
+ # [:a,:two,:baz] => 2,
58
+ # [:b,:one,:bar] => 3,
59
+ # [:b,:two,:bar] => 4
60
+ # })
61
+ # end
62
+ end
63
+ end
64
+
65
+ describe "#to_json" do
66
+ subject { vector.to_json }
67
+
68
+ let(:vector) do
69
+ DaruLite::Vector.new(
70
+ [1,2,3,4,5],
71
+ name: :a,
72
+ index: [:one, :two, :three, :four, :five],
73
+ dtype: dtype
74
+ )
75
+ end
76
+
77
+ it "returns the vector as json" do
78
+ expect(subject).to eq(vector.to_h.to_json)
79
+ end
80
+
81
+ end
82
+
83
+ describe "#to_s" do
84
+ let(:vector) { DaruLite::Vector.new(["a", "b"], index: [1, 2], name:) }
85
+
86
+ context 'name is nil' do
87
+ let(:name) { nil }
88
+
89
+ it 'produces a class, size description' do
90
+ expect(vector.to_s).to eq("#<DaruLite::Vector(2)>")
91
+ end
92
+ end
93
+
94
+ context 'name is present' do
95
+ let(:name) { "Test" }
96
+
97
+ it 'produces a class, name, size description' do
98
+ expect(vector.to_s).to eq("#<DaruLite::Vector: Test(2)>")
99
+ end
100
+ end
101
+
102
+ context 'name is a symbol' do
103
+ let(:name) { :Test }
104
+
105
+ it 'produces a class, name, size description' do
106
+ expect(vector.to_s).to eq("#<DaruLite::Vector: Test(2)>")
107
+ end
108
+ end
109
+ end
110
+
111
+ describe "#to_matrix" do
112
+ let(:vector) { DaruLite::Vector.new [1, 2, 3, 4, 5, 6] }
113
+
114
+ it "converts DaruLite::Vector to a horizontal Ruby Matrix" do
115
+ expect(vector.to_matrix).to eq(Matrix[[1, 2, 3, 4, 5, 6]])
116
+ end
117
+
118
+ it "converts DaruLite::Vector to a vertical Ruby Matrix" do
119
+ expect(vector.to_matrix(:vertical)).to eq(Matrix.columns([[1, 2, 3, 4, 5, 6]]))
120
+ end
121
+
122
+ it 'raises on wrong axis' do
123
+ expect { vector.to_matrix(:strange) }.to raise_error(ArgumentError)
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,48 @@
1
+ shared_examples_for 'a duplicatable Vector' do
2
+ describe "#dup" do
3
+ subject { vector.dup }
4
+
5
+ let(:vector) do
6
+ DaruLite::Vector.new([1, 2], name: :yoda, index: [:happy, :lightsaber])
7
+ end
8
+
9
+ it "copies the original data" do
10
+ expect(subject.send(:data)).to eq([1,2])
11
+ end
12
+
13
+ it "creates a new data object" do
14
+ expect(subject.send(:data).object_id).not_to eq(vector.send(:data).object_id)
15
+ end
16
+
17
+ it "copies the name" do
18
+ expect(subject.name).to eq(:yoda)
19
+ end
20
+
21
+ it "copies the original index" do
22
+ expect(subject.index).to eq(DaruLite::Index.new([:happy, :lightsaber]))
23
+ end
24
+
25
+ it "creates a new index object" do
26
+ expect(subject.index.object_id).not_to eq(vector.index.object_id)
27
+ end
28
+ end
29
+
30
+ describe "#clone_structure" do
31
+ subject { vector.clone_structure }
32
+ context DaruLite::Index do
33
+ let(:vector) do
34
+ DaruLite::Vector.new([1, 2, 3, 4, 5], index: [:a,:b,:c,:d,:e])
35
+ end
36
+
37
+ it "clones a vector with its index and fills it with nils" do
38
+ expect(subject).to eq(
39
+ DaruLite::Vector.new([nil, nil, nil, nil, nil], index: [:a,:b,:c,:d,:e])
40
+ )
41
+ end
42
+ end
43
+
44
+ context DaruLite::MultiIndex do
45
+ pending
46
+ end
47
+ end
48
+ end