daru 0.1.5 → 0.1.6

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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +20 -7
  3. data/CONTRIBUTING.md +1 -1
  4. data/History.md +48 -1
  5. data/README.md +3 -3
  6. data/benchmarks/statistics.rb +6 -6
  7. data/benchmarks/where_clause.rb +1 -1
  8. data/benchmarks/where_vs_filter.rb +1 -1
  9. data/daru.gemspec +3 -2
  10. data/lib/daru.rb +14 -6
  11. data/lib/daru/accessors/gsl_wrapper.rb +1 -1
  12. data/lib/daru/accessors/nmatrix_wrapper.rb +2 -0
  13. data/lib/daru/category.rb +1 -1
  14. data/lib/daru/core/group_by.rb +32 -15
  15. data/lib/daru/core/query.rb +4 -4
  16. data/lib/daru/dataframe.rb +196 -48
  17. data/lib/daru/date_time/index.rb +7 -5
  18. data/lib/daru/formatters/table.rb +1 -0
  19. data/lib/daru/index/index.rb +121 -33
  20. data/lib/daru/index/multi_index.rb +83 -3
  21. data/lib/daru/io/csv/converters.rb +18 -0
  22. data/lib/daru/io/io.rb +80 -11
  23. data/lib/daru/io/sql_data_source.rb +10 -0
  24. data/lib/daru/iruby/templates/dataframe.html.erb +3 -50
  25. data/lib/daru/iruby/templates/dataframe_mi.html.erb +3 -56
  26. data/lib/daru/iruby/templates/dataframe_mi_tbody.html.erb +35 -0
  27. data/lib/daru/iruby/templates/dataframe_mi_thead.html.erb +21 -0
  28. data/lib/daru/iruby/templates/dataframe_tbody.html.erb +28 -0
  29. data/lib/daru/iruby/templates/dataframe_thead.html.erb +21 -0
  30. data/lib/daru/iruby/templates/vector.html.erb +3 -25
  31. data/lib/daru/iruby/templates/vector_mi.html.erb +3 -34
  32. data/lib/daru/iruby/templates/vector_mi_tbody.html.erb +26 -0
  33. data/lib/daru/iruby/templates/vector_mi_thead.html.erb +8 -0
  34. data/lib/daru/iruby/templates/vector_tbody.html.erb +17 -0
  35. data/lib/daru/iruby/templates/vector_thead.html.erb +8 -0
  36. data/lib/daru/maths/statistics/dataframe.rb +9 -11
  37. data/lib/daru/maths/statistics/vector.rb +139 -32
  38. data/lib/daru/plotting/gruff/dataframe.rb +13 -15
  39. data/lib/daru/plotting/nyaplot/category.rb +1 -1
  40. data/lib/daru/plotting/nyaplot/dataframe.rb +4 -4
  41. data/lib/daru/plotting/nyaplot/vector.rb +1 -2
  42. data/lib/daru/vector.rb +169 -80
  43. data/lib/daru/version.rb +1 -1
  44. data/spec/category_spec.rb +19 -19
  45. data/spec/core/group_by_spec.rb +47 -0
  46. data/spec/core/query_spec.rb +55 -50
  47. data/spec/daru_spec.rb +22 -0
  48. data/spec/dataframe_spec.rb +118 -6
  49. data/spec/date_time/index_spec.rb +34 -16
  50. data/spec/extensions/rserve_spec.rb +1 -1
  51. data/spec/fixtures/boolean_converter_test.csv +5 -0
  52. data/spec/fixtures/eciresults.html +394 -0
  53. data/spec/fixtures/empty_rows_test.csv +17 -0
  54. data/spec/fixtures/macau.html +3691 -0
  55. data/spec/fixtures/macd_data.csv +150 -0
  56. data/spec/fixtures/moneycontrol.html +6812 -0
  57. data/spec/fixtures/url_test.txt~ +0 -0
  58. data/spec/fixtures/valid_markup.html +62 -0
  59. data/spec/fixtures/wiki_climate.html +1243 -0
  60. data/spec/fixtures/wiki_table_info.html +631 -0
  61. data/spec/formatters/table_formatter_spec.rb +29 -0
  62. data/spec/index/categorical_index_spec.rb +33 -33
  63. data/spec/index/index_spec.rb +134 -41
  64. data/spec/index/multi_index_spec.rb +115 -31
  65. data/spec/io/io_spec.rb +201 -0
  66. data/spec/io/sql_data_source_spec.rb +31 -41
  67. data/spec/iruby/dataframe_spec.rb +17 -19
  68. data/spec/iruby/vector_spec.rb +26 -28
  69. data/spec/maths/statistics/vector_spec.rb +136 -14
  70. data/spec/plotting/gruff/category_spec.rb +3 -3
  71. data/spec/plotting/gruff/dataframe_spec.rb +14 -4
  72. data/spec/plotting/gruff/vector_spec.rb +9 -9
  73. data/spec/plotting/nyaplot/category_spec.rb +5 -9
  74. data/spec/plotting/nyaplot/dataframe_spec.rb +72 -47
  75. data/spec/plotting/nyaplot/vector_spec.rb +5 -11
  76. data/spec/shared/vector_display_spec.rb +12 -14
  77. data/spec/spec_helper.rb +21 -0
  78. data/spec/support/matchers.rb +5 -0
  79. data/spec/vector_spec.rb +222 -72
  80. metadata +68 -23
  81. data/spec/fixtures/stock_data.csv +0 -500
@@ -12,24 +12,21 @@ describe Daru::Vector, 'plotting' do
12
12
 
13
13
  it 'plots the vector' do
14
14
  expect(plot).to receive(:add).with(:box, [11, 22, 33]).ordered
15
- expect(plot).to receive(:show).ordered
16
15
 
17
- vector.plot(type: :box)
16
+ expect(vector.plot(type: :box)).to eq plot
18
17
  end
19
18
 
20
19
  context 'scatter' do
21
20
  it 'is default type' do
22
21
  expect(plot).to receive(:add).with(:scatter, instance_of(Array), instance_of(Array)).ordered
23
- expect(plot).to receive(:show).ordered
24
22
 
25
- vector.plot
23
+ expect(vector.plot).to eq plot
26
24
  end
27
25
 
28
26
  it 'sets x_axis to 0...size' do
29
27
  expect(plot).to receive(:add).with(:scatter, [0, 1, 2], [11, 22, 33]).ordered
30
- expect(plot).to receive(:show).ordered
31
28
 
32
- vector.plot(type: :scatter)
29
+ expect(vector.plot(type: :scatter)).to eq plot
33
30
  end
34
31
  end
35
32
 
@@ -37,9 +34,8 @@ describe Daru::Vector, 'plotting' do
37
34
  context type.to_s do
38
35
  it 'does not set x axis' do
39
36
  expect(plot).to receive(:add).with(type, [11, 22, 33]).ordered
40
- expect(plot).to receive(:show).ordered
41
37
 
42
- vector.plot(type: type)
38
+ expect(vector.plot(type: type)).to eq plot
43
39
  end
44
40
  end
45
41
  end
@@ -48,9 +44,8 @@ describe Daru::Vector, 'plotting' do
48
44
  context type.to_s do
49
45
  it 'sets x axis to index' do
50
46
  expect(plot).to receive(:add).with(type, [:a, :b, :c], [11, 22, 33]).ordered
51
- expect(plot).to receive(:show).ordered
52
47
 
53
- vector.plot(type: type)
48
+ expect(vector.plot(type: type)).to eq plot
54
49
  end
55
50
  end
56
51
  end
@@ -58,7 +53,6 @@ describe Daru::Vector, 'plotting' do
58
53
  context 'with block provided' do
59
54
  it 'yields plot and diagram' do
60
55
  expect(plot).to receive(:add).with(:box, [11, 22, 33]).ordered.and_return(diagram)
61
- expect(plot).to receive(:show).ordered
62
56
 
63
57
  expect { |b| vector.plot(type: :box, &b) }.to yield_with_args(plot, diagram)
64
58
  end
@@ -109,7 +109,7 @@ describe Daru::Vector do
109
109
  context '#to_html' do
110
110
  let(:doc) { Nokogiri::HTML(vector.to_html) }
111
111
  subject(:table) { doc.at('table') }
112
- let(:header) { table.at('tr:first-child > th:first-child') }
112
+ let(:header) { doc.at('b') }
113
113
 
114
114
  context 'simple' do
115
115
  let(:vector) { Daru::Vector.new [1,nil,3],
@@ -119,13 +119,12 @@ describe Daru::Vector do
119
119
  describe 'header' do
120
120
  subject { header }
121
121
  it { is_expected.not_to be_nil }
122
- its(['colspan']) { is_expected.to eq '2' }
123
- its(:text) { is_expected.to eq "Daru::Vector(3)"\
124
- "#{":category" if type == :category}" }
122
+ its(:text) { is_expected.to eq " Daru::Vector(3)"\
123
+ "#{":category" if type == :category} " }
125
124
  end
126
125
 
127
126
  describe 'name' do
128
- subject(:name) { table.at('tr:nth-child(2) > th:nth-child(2)') }
127
+ subject(:name) { table.at('thead > tr:first-child > th:nth-child(2)') }
129
128
  it { is_expected.not_to be_nil }
130
129
  its(:text) { is_expected.to eq 'test' }
131
130
 
@@ -151,18 +150,18 @@ describe Daru::Vector do
151
150
 
152
151
  context 'large vector' do
153
152
  subject(:vector) { Daru::Vector.new [1,2,3] * 100, name: 'test', type: type }
154
- it 'has only 30 rows (+ 2 header rows, + 2 finishing rows)' do
155
- expect(table.search('tr').size).to eq 34
153
+ it 'has only 30 rows (+ 1 header rows, + 2 finishing rows)' do
154
+ expect(table.search('tr').size).to eq 33
156
155
  end
157
156
 
158
157
  describe '"skipped" row' do
159
- subject(:row) { table.search('tr:nth-child(33) td').map(&:text) }
158
+ subject(:row) { table.search('tr:nth-child(31) td').map(&:text) }
160
159
  its(:count) { is_expected.to eq 2 }
161
160
  it { is_expected.to eq ['...', '...'] }
162
161
  end
163
162
 
164
163
  describe 'last row' do
165
- subject(:row) { table.search('tr:nth-child(34) td').map(&:text) }
164
+ subject(:row) { table.search('tr:nth-child(32) td').map(&:text) }
166
165
  its(:count) { is_expected.to eq 2 }
167
166
  it { is_expected.to eq ['299', '3'] }
168
167
  end
@@ -189,19 +188,18 @@ describe Daru::Vector do
189
188
  describe 'header' do
190
189
  subject { header }
191
190
  it { is_expected.not_to be_nil }
192
- its(['colspan']) { is_expected.to eq '3' }
193
- its(:text) { is_expected.to eq "Daru::Vector(7)"\
194
- "#{":category" if type == :category}" }
191
+ its(:text) { is_expected.to eq " Daru::Vector(7)"\
192
+ "#{":category" if type == :category} " }
195
193
  end
196
194
 
197
195
  describe 'name row' do
198
- subject(:row) { table.at('tr:nth-child(2)').search('th') }
196
+ subject(:row) { table.at('thead > tr:nth-child(1)').search('th') }
199
197
  its(:count) { should == 2 }
200
198
  it { expect(row.first['colspan']).to eq '2' }
201
199
  end
202
200
 
203
201
  describe 'first data row' do
204
- let(:row) { table.at('tr:nth-child(3)') }
202
+ let(:row) { table.at('tbody > tr:first-child') }
205
203
  subject { row.inner_html.scan(/<t[dh].+?<\/t[dh]>/) }
206
204
  it { is_expected.to eq [
207
205
  '<th rowspan="3">foo</th>',
@@ -1,5 +1,6 @@
1
1
  require 'rspec'
2
2
  require 'rspec/its'
3
+ require 'rspec/expectations'
3
4
  require 'matrix'
4
5
  require 'awesome_print'
5
6
  require 'distribution'
@@ -7,6 +8,7 @@ require 'tempfile'
7
8
  require 'pry-byebug'
8
9
  require 'nokogiri'
9
10
  require 'gruff'
11
+ require 'webmock/rspec'
10
12
 
11
13
  def mri?
12
14
  RUBY_ENGINE == 'ruby'
@@ -51,6 +53,25 @@ def expect_correct_df_in_delta df1, df2, delta
51
53
  end
52
54
  end
53
55
 
56
+ RSpec::Matchers.define :be_all_within do |delta|
57
+ match do |actual|
58
+ expect(@expected).to_not be_nil
59
+ expect(actual.size).to equal(actual.size)
60
+ (@act, @exp), @idx = actual.zip(@expected).each_with_index.detect { |(a, e), _| (a - e).abs > delta }
61
+ @idx.nil?
62
+ end
63
+
64
+ chain :of do |expected|
65
+ @expected = expected
66
+ end
67
+
68
+ failure_message do |actual|
69
+ return "expected value must be provided using '.of'." if @expected.nil?
70
+ return "expected.size must equal actual.size." if @expected.size != actual.size
71
+ "at index=[#{@idx}], expected '#{actual[@idx]}' to be within '#{delta}' of '#{@expected[@idx]}'."
72
+ end
73
+ end
74
+
54
75
  class String
55
76
  # allows to pretty test agains multiline strings:
56
77
  # %Q{
@@ -0,0 +1,5 @@
1
+ RSpec::Matchers.define :be_boolean do
2
+ match do |actual|
3
+ expect(actual.is_a?(TrueClass) || actual.is_a?(FalseClass)).to be true
4
+ end
5
+ end
@@ -84,6 +84,11 @@ describe Daru::Vector do
84
84
  expect(dv.index.to_a).to eq(['a', 'b', :r, 0])
85
85
  end
86
86
 
87
+ it "initializes array with nils with dtype NMatrix" do
88
+ dv = Daru::Vector.new [2, nil], dtype: :nmatrix
89
+ expect(dv.to_a).to eq([2, nil])
90
+ expect(dv.index.to_a).to eq([0, 1])
91
+ end
87
92
  end
88
93
 
89
94
  context "#reorder!" do
@@ -358,6 +363,9 @@ describe Daru::Vector do
358
363
  let (:idx) { Daru::Index.new [1, 0, :c] }
359
364
  let (:dv) { Daru::Vector.new ['a', 'b', 'c'], index: idx }
360
365
 
366
+ let (:idx_dt) { Daru::DateTimeIndex.new(['2017-01-01', '2017-02-01', '2017-03-01']) }
367
+ let (:dv_dt) { Daru::Vector.new(['a', 'b', 'c'], index: idx_dt) }
368
+
361
369
  context "single position" do
362
370
  it { expect(dv.at 1).to eq 'b' }
363
371
  end
@@ -405,6 +413,15 @@ describe Daru::Vector do
405
413
  its(:to_a) { is_expected.to eq ['a'] }
406
414
  its(:'index.to_a') { is_expected.to eq [1] }
407
415
  end
416
+
417
+ context "Splat .at on DateTime index" do
418
+ subject { dv_dt.at(*[1,2]) }
419
+
420
+ it { is_expected.to be_a Daru::Vector }
421
+ its(:size) { is_expected.to eq 2 }
422
+ its(:to_a) { is_expected.to eq ['b', 'c'] }
423
+ its(:'index.to_a') { is_expected.to eq ['2017-02-01', '2017-03-01'] }
424
+ end
408
425
  end
409
426
 
410
427
  context Daru::MultiIndex do
@@ -998,6 +1015,26 @@ describe Daru::Vector do
998
1015
  its(:to_json) { is_expected.to eq(vector.to_h.to_json) }
999
1016
  end
1000
1017
 
1018
+ context "#to_s" do
1019
+ before do
1020
+ @v = Daru::Vector.new ["a", "b"], index: [1, 2]
1021
+ end
1022
+
1023
+ it 'produces a class, size description' do
1024
+ expect(@v.to_s).to eq("#<Daru::Vector(2)>")
1025
+ end
1026
+
1027
+ it 'produces a class, name, size description' do
1028
+ @v.name = "Test"
1029
+ expect(@v.to_s).to eq("#<Daru::Vector: Test(2)>")
1030
+ end
1031
+
1032
+ it 'produces a class, name, size description when the name is a symbol' do
1033
+ @v.name = :Test
1034
+ expect(@v.to_s).to eq("#<Daru::Vector: Test(2)>")
1035
+ end
1036
+ end
1037
+
1001
1038
  context "#uniq" do
1002
1039
  before do
1003
1040
  @v = Daru::Vector.new [1, 2, 2, 2.0, 3, 3.0], index:[:a, :b, :c, :d, :e, :f]
@@ -1359,8 +1396,75 @@ describe Daru::Vector do
1359
1396
  end
1360
1397
 
1361
1398
  context "#summary" do
1362
- it "has name in the summary" do
1363
- expect(@common_all_dtypes.summary.match("#{@common_all_dtypes.name}")).to_not eq(nil)
1399
+ subject { dv.summary }
1400
+
1401
+ context 'all types' do
1402
+ let(:dv) { Daru::Vector.new([1,2,3,4,5], name: 'vector') }
1403
+
1404
+ it { is_expected.to include dv.name }
1405
+
1406
+ it { is_expected.to include "n :#{dv.size}" }
1407
+
1408
+ it { is_expected.to include "non-missing:#{dv.size - dv.count_values(*Daru::MISSING_VALUES)}" }
1409
+ end
1410
+
1411
+ unless dtype == :nmatrix
1412
+ context "numeric type" do
1413
+ let(:dv) { Daru::Vector.new([1,2,5], name: 'numeric') }
1414
+
1415
+ it { is_expected. to eq %Q{
1416
+ |= numeric
1417
+ | n :3
1418
+ | non-missing:3
1419
+ | median: 2
1420
+ | mean: 2.6667
1421
+ | std.dev.: 2.0817
1422
+ | std.err.: 1.2019
1423
+ | skew: 0.2874
1424
+ | kurtosis: -2.3333
1425
+ }.unindent }
1426
+ end
1427
+
1428
+ context "numeric type with missing values" do
1429
+ let(:dv) { Daru::Vector.new([1,2,5,nil,Float::NAN], name: 'numeric') }
1430
+
1431
+ it { is_expected.not_to include 'skew' }
1432
+ it { is_expected.not_to include 'kurtosis' }
1433
+ end
1434
+ end
1435
+
1436
+ if dtype == :array
1437
+ context "object type" do
1438
+ let(:dv) { Daru::Vector.new([1,1,2,2,"string",nil,Float::NAN], name: 'object') }
1439
+
1440
+ if RUBY_VERSION >= '2.2'
1441
+ it { is_expected.to eq %Q{
1442
+ |= object
1443
+ | n :7
1444
+ | non-missing:5
1445
+ | factors: 1,2,string
1446
+ | mode: 1,2
1447
+ | Distribution
1448
+ | string 1 50.00%
1449
+ | NaN 1 50.00%
1450
+ | 1 2 100.00%
1451
+ | 2 2 100.00%
1452
+ }.unindent }
1453
+ else
1454
+ it { is_expected.to eq %Q{
1455
+ |= object
1456
+ | n :7
1457
+ | non-missing:5
1458
+ | factors: 1,2,string
1459
+ | mode: 1,2
1460
+ | Distribution
1461
+ | NaN 1 50.00%
1462
+ | string 1 50.00%
1463
+ | 2 2 100.00%
1464
+ | 1 2 100.00%
1465
+ }.unindent }
1466
+ end
1467
+ end
1364
1468
  end
1365
1469
  end
1366
1470
 
@@ -1388,27 +1492,19 @@ describe Daru::Vector do
1388
1492
  end
1389
1493
  end
1390
1494
 
1391
- context "#is_nil?" do
1392
- before(:each) do
1393
- @with_md = Daru::Vector.new([1,2,nil,3,4,nil])
1394
- @without_md = Daru::Vector.new([1,2,3,4,5,6])
1395
- end
1396
-
1397
- it "verifies missing data presence" do
1398
- expect(@with_md.is_nil?) .to eq(Daru::Vector.new([false,false,true,false,false,true]))
1399
- expect(@without_md.is_nil?).to eq(Daru::Vector.new([false,false,false,false,false,false]))
1400
- end
1401
- end
1495
+ context '#is_values' do
1496
+ let(:dv) { Daru::Vector.new [10, 11, 10, nil, nil] }
1402
1497
 
1403
- context "#not_nil?" do
1404
- before(:each) do
1405
- @with_md = Daru::Vector.new([1,2,nil,3,4,nil])
1406
- @without_md = Daru::Vector.new([1,2,3,4,5,6])
1498
+ context 'single value' do
1499
+ subject { dv.is_values 10 }
1500
+ it { is_expected.to be_a Daru::Vector }
1501
+ its(:to_a) { is_expected.to eq [true, false, true, false, false] }
1407
1502
  end
1408
1503
 
1409
- it "verifies missing data presence" do
1410
- expect(@with_md.not_nil?) .to eq(Daru::Vector.new([true,true,false,true,true,false]))
1411
- expect(@without_md.not_nil?).to eq(Daru::Vector.new([true,true,true,true,true,true]))
1504
+ context 'multiple values' do
1505
+ subject { dv.is_values 10, nil }
1506
+ it { is_expected.to be_a Daru::Vector }
1507
+ its(:to_a) { is_expected.to eq [true, false, true, true, true] }
1412
1508
  end
1413
1509
  end
1414
1510
 
@@ -1433,7 +1529,7 @@ describe Daru::Vector do
1433
1529
  index: 11..18 }
1434
1530
  context 'reject only nils' do
1435
1531
  subject { dv.reject_values nil }
1436
-
1532
+
1437
1533
  it { is_expected.to be_a Daru::Vector }
1438
1534
  its(:to_a) { is_expected.to eq [1, 3, :a, Float::NAN, Float::NAN, 1] }
1439
1535
  its(:'index.to_a') { is_expected.to eq [11, 13, 14, 15, 17, 18] }
@@ -1441,7 +1537,7 @@ describe Daru::Vector do
1441
1537
 
1442
1538
  context 'reject only float::NAN' do
1443
1539
  subject { dv.reject_values Float::NAN }
1444
-
1540
+
1445
1541
  it { is_expected.to be_a Daru::Vector }
1446
1542
  its(:to_a) { is_expected.to eq [1, nil, 3, :a, nil, 1] }
1447
1543
  its(:'index.to_a') { is_expected.to eq [11, 12, 13, 14, 16, 18] }
@@ -1449,15 +1545,15 @@ describe Daru::Vector do
1449
1545
 
1450
1546
  context 'reject both nil and float::NAN' do
1451
1547
  subject { dv.reject_values nil, Float::NAN }
1452
-
1548
+
1453
1549
  it { is_expected.to be_a Daru::Vector }
1454
1550
  its(:to_a) { is_expected.to eq [1, 3, :a, 1] }
1455
1551
  its(:'index.to_a') { is_expected.to eq [11, 13, 14, 18] }
1456
1552
  end
1457
-
1553
+
1458
1554
  context 'reject any other value' do
1459
1555
  subject { dv.reject_values 1, 3 }
1460
-
1556
+
1461
1557
  it { is_expected.to be_a Daru::Vector }
1462
1558
  its(:to_a) { is_expected.to eq [nil, :a, Float::NAN, nil, Float::NAN] }
1463
1559
  its(:'index.to_a') { is_expected.to eq [12, 14, 15, 16, 17] }
@@ -1465,25 +1561,25 @@ describe Daru::Vector do
1465
1561
 
1466
1562
  context 'when resultant vector has only one value' do
1467
1563
  subject { dv.reject_values 1, :a, nil, Float::NAN }
1468
-
1564
+
1469
1565
  it { is_expected.to be_a Daru::Vector }
1470
1566
  its(:to_a) { is_expected.to eq [3] }
1471
1567
  its(:'index.to_a') { is_expected.to eq [13] }
1472
1568
  end
1473
-
1569
+
1474
1570
  context 'when resultant vector has no value' do
1475
1571
  subject { dv.reject_values 1, 3, :a, nil, Float::NAN, 5 }
1476
-
1572
+
1477
1573
  it { is_expected.to be_a Daru::Vector }
1478
1574
  its(:to_a) { is_expected.to eq [] }
1479
1575
  its(:'index.to_a') { is_expected.to eq [] }
1480
1576
  end
1481
-
1577
+
1482
1578
  context 'works for gsl' do
1483
1579
  let(:dv) { Daru::Vector.new [1, 2, 3, Float::NAN], dtype: :gsl,
1484
1580
  index: 11..14 }
1485
1581
  subject { dv.reject_values Float::NAN }
1486
-
1582
+
1487
1583
  it { is_expected.to be_a Daru::Vector }
1488
1584
  its(:dtype) { is_expected.to eq :gsl }
1489
1585
  its(:to_a) { is_expected.to eq [1, 2, 3].map(&:to_f) }
@@ -1501,31 +1597,31 @@ describe Daru::Vector do
1501
1597
 
1502
1598
  context 'reject only nils' do
1503
1599
  subject { dv.reject_values nil }
1504
-
1600
+
1505
1601
  it { is_expected.to be_a Daru::Vector }
1506
1602
  its(:to_a) { is_expected.to eq [1, 3, :a, Float::NAN, Float::NAN, 1] }
1507
1603
  its(:'index.to_a') { is_expected.to eq [11, 13, 14, 15, 17, 18] }
1508
1604
  end
1509
-
1605
+
1510
1606
  context 'reject only float::NAN' do
1511
1607
  subject { dv.reject_values Float::NAN }
1512
-
1608
+
1513
1609
  it { is_expected.to be_a Daru::Vector }
1514
1610
  its(:to_a) { is_expected.to eq [1, nil, 3, :a, nil, 1] }
1515
1611
  its(:'index.to_a') { is_expected.to eq [11, 12, 13, 14, 16, 18] }
1516
1612
  end
1517
-
1613
+
1518
1614
  context 'reject both nil and float::NAN' do
1519
1615
  subject { dv.reject_values nil, Float::NAN }
1520
-
1616
+
1521
1617
  it { is_expected.to be_a Daru::Vector }
1522
1618
  its(:to_a) { is_expected.to eq [1, 3, :a, 1] }
1523
1619
  its(:'index.to_a') { is_expected.to eq [11, 13, 14, 18] }
1524
1620
  end
1525
-
1621
+
1526
1622
  context 'reject any other value' do
1527
1623
  subject { dv.reject_values 1, 3 }
1528
-
1624
+
1529
1625
  it { is_expected.to be_a Daru::Vector }
1530
1626
  its(:to_a) { is_expected.to eq [nil, :a, Float::NAN, nil, Float::NAN] }
1531
1627
  its(:'index.to_a') { is_expected.to eq [12, 14, 15, 16, 17] }
@@ -1563,24 +1659,24 @@ describe Daru::Vector do
1563
1659
  let(:dv) { Daru::Vector.new [1, Float::NAN, 2, 3] }
1564
1660
  it { expect(dv.include_values? nil, Float::NAN).to eq true }
1565
1661
  end
1566
-
1662
+
1567
1663
  context 'true with only Float::NAN' do
1568
1664
  let(:dv) { Daru::Vector.new [1, nil, 2, 3] }
1569
1665
  it { expect(dv.include_values? nil, Float::NAN).to eq true }
1570
1666
  end
1571
-
1667
+
1572
1668
  context 'false' do
1573
1669
  let(:dv) { Daru::Vector.new [1, 2, 3] }
1574
1670
  it { expect(dv.include_values? nil, Float::NAN).to eq false }
1575
1671
  end
1576
1672
  end
1577
-
1673
+
1578
1674
  context 'any other value' do
1579
1675
  context 'true' do
1580
1676
  let(:dv) { Daru::Vector.new [1, 2, 3, 4, nil] }
1581
1677
  it { expect(dv.include_values? 1, 2, 3, 5).to eq true }
1582
1678
  end
1583
-
1679
+
1584
1680
  context 'false' do
1585
1681
  let(:dv) { Daru::Vector.new [1, 2, 3, 4, nil] }
1586
1682
  it { expect(dv.include_values? 5, 6).to eq false }
@@ -1600,12 +1696,12 @@ describe Daru::Vector do
1600
1696
  context Daru::Index do
1601
1697
  let(:dv) { Daru::Vector.new [1, 2, 1, 2, 3, nil, nil, Float::NAN],
1602
1698
  index: 11..18 }
1603
-
1699
+
1604
1700
  subject { dv.indexes 1, 2, nil, Float::NAN }
1605
1701
  it { is_expected.to be_a Array }
1606
1702
  it { is_expected.to eq [11, 12, 13, 14, 16, 17, 18] }
1607
1703
  end
1608
-
1704
+
1609
1705
  context Daru::MultiIndex do
1610
1706
  let(:mi) do
1611
1707
  Daru::MultiIndex.from_tuples([
@@ -1621,7 +1717,7 @@ describe Daru::Vector do
1621
1717
  end
1622
1718
  let(:dv) { Daru::Vector.new [1, 2, 1, 2, 3, nil, nil, Float::NAN],
1623
1719
  index: mi }
1624
-
1720
+
1625
1721
  subject { dv.indexes 1, 2, Float::NAN }
1626
1722
  it { is_expected.to be_a Array }
1627
1723
  it { is_expected.to eq(
@@ -1634,7 +1730,7 @@ describe Daru::Vector do
1634
1730
  ]) }
1635
1731
  end
1636
1732
  end
1637
-
1733
+
1638
1734
  context '#replace_values' do
1639
1735
  subject do
1640
1736
  Daru::Vector.new(
@@ -1647,13 +1743,13 @@ describe Daru::Vector do
1647
1743
  before { subject.replace_values [nil, Float::NAN], 10 }
1648
1744
  its(:to_a) { is_expected.to eq [1, 2, 1, 4, 10, 10, 10, 10] }
1649
1745
  end
1650
-
1746
+
1651
1747
  context 'replace arbitrary values' do
1652
1748
  before { subject.replace_values [1, 2], 10 }
1653
1749
  its(:to_a) { is_expected.to eq(
1654
1750
  [10, 10, 10, 4, nil, Float::NAN, nil, Float::NAN]) }
1655
1751
  end
1656
-
1752
+
1657
1753
  context 'works for single value' do
1658
1754
  before { subject.replace_values nil, 10 }
1659
1755
  its(:to_a) { is_expected.to eq(
@@ -1741,7 +1837,7 @@ describe Daru::Vector do
1741
1837
 
1742
1838
  context '#to_nmatrix' do
1743
1839
  let(:dv) { Daru::Vector.new [1, 2, 3, 4, 5] }
1744
-
1840
+
1745
1841
  context 'horizontal axis' do
1746
1842
  subject { dv.to_nmatrix }
1747
1843
 
@@ -1749,19 +1845,19 @@ describe Daru::Vector do
1749
1845
  its(:shape) { is_expected.to eq [1, 5] }
1750
1846
  its(:to_a) { is_expected.to eq [1, 2, 3, 4, 5] }
1751
1847
  end
1752
-
1848
+
1753
1849
  context 'vertical axis' do
1754
1850
  subject { dv.to_nmatrix :vertical }
1755
-
1851
+
1756
1852
  it { is_expected.to be_a NMatrix }
1757
1853
  its(:shape) { is_expected.to eq [5, 1] }
1758
1854
  its(:to_a) { is_expected.to eq [1, 2, 3, 4, 5].map { |i| [i] } }
1759
1855
  end
1760
-
1856
+
1761
1857
  context 'invalid axis' do
1762
1858
  it { expect { dv.to_nmatrix :hello }.to raise_error ArgumentError }
1763
1859
  end
1764
-
1860
+
1765
1861
  context 'vector contain non-numeric' do
1766
1862
  let(:dv) { Daru::Vector.new [1, 2, nil, 4] }
1767
1863
  it { expect { dv.to_nmatrix }.to raise_error ArgumentError }
@@ -1904,46 +2000,73 @@ describe Daru::Vector do
1904
2000
  end
1905
2001
  end
1906
2002
 
1907
- context "#lag" do
1908
- before do
1909
- @xiu = Daru::Vector.new([17.28, 17.45, 17.84, 17.74, 17.82, 17.85, 17.36, 17.3, 17.56, 17.49, 17.46, 17.4, 17.03, 17.01,
1910
- 16.86, 16.86, 16.56, 16.36, 16.66, 16.77])
2003
+ describe '#lag' do
2004
+ let(:source) { Daru::Vector.new(1..5) }
2005
+
2006
+ context 'by default' do
2007
+ subject { source.lag }
2008
+ it { is_expected.to eq Daru::Vector.new([nil, 1, 2, 3, 4]) }
2009
+ end
2010
+
2011
+ subject { source.lag(amount) }
2012
+
2013
+ context '0' do
2014
+ let(:amount) { 0 }
2015
+ it { is_expected.to eq Daru::Vector.new([1, 2, 3, 4, 5]) }
2016
+ end
2017
+
2018
+ context 'same as vector size' do
2019
+ let(:amount) { source.size }
2020
+ it { is_expected.to eq Daru::Vector.new([nil]*source.size) }
1911
2021
  end
1912
2022
 
1913
- it "lags the vector by specified amount" do
1914
- lag1 = @xiu.lag
2023
+ context 'same as vector -ve size' do
2024
+ let(:amount) { -source.size }
2025
+ it { is_expected.to eq Daru::Vector.new([nil]*source.size) }
2026
+ end
2027
+
2028
+ context 'positive' do
2029
+ let(:amount) { 2 }
2030
+ it { is_expected.to eq Daru::Vector.new([nil, nil, 1, 2, 3]) }
2031
+ end
1915
2032
 
1916
- expect(lag1[lag1.size - 1]).to be_within(0.001).of(16.66)
1917
- expect(lag1[lag1.size - 2]).to be_within(0.001).of(16.36)
2033
+ context 'negative' do
2034
+ let(:amount) { -1 }
2035
+ it { is_expected.to eq Daru::Vector.new([2, 3, 4, 5, nil]) }
2036
+ end
1918
2037
 
1919
- #test with different lagging unit
1920
- lag2 = @xiu.lag(2)
2038
+ context 'large positive' do
2039
+ let(:amount) { source.size + 100 }
2040
+ it { is_expected.to eq Daru::Vector.new([nil]*source.size) }
2041
+ end
1921
2042
 
1922
- expect(lag2[lag2.size - 1]).to be_within(0.001).of(16.36)
1923
- expect(lag2[lag2.size - 2]).to be_within(0.001).of(16.56)
2043
+ context 'large negative' do
2044
+ let(:amount) { -(source.size + 100) }
2045
+ it { is_expected.to eq Daru::Vector.new([nil]*source.size) }
1924
2046
  end
2047
+
1925
2048
  end
1926
-
2049
+
1927
2050
  context "#group_by" do
1928
2051
  let(:dv) { Daru::Vector.new [:a, :b, :a, :b, :c] }
1929
-
2052
+
1930
2053
  context 'vector not specified' do
1931
- subject { dv.group_by }
1932
-
2054
+ subject { dv.group_by }
2055
+
1933
2056
  it { is_expected.to be_a Daru::Core::GroupBy }
1934
2057
  its(:'groups.size') { is_expected.to eq 3 }
1935
2058
  its(:groups) { is_expected.to eq({[:a]=>[0, 2], [:b]=>[1, 3], [:c]=>[4]}) }
1936
2059
  end
1937
-
2060
+
1938
2061
  context 'vector name specified' do
1939
2062
  before { dv.name = :hello }
1940
2063
  subject { dv.group_by :hello }
1941
-
2064
+
1942
2065
  it { is_expected.to be_a Daru::Core::GroupBy }
1943
2066
  its(:'groups.size') { is_expected.to eq 3 }
1944
- its(:groups) { is_expected.to eq({[:a]=>[0, 2], [:b]=>[1, 3], [:c]=>[4]}) }
2067
+ its(:groups) { is_expected.to eq({[:a]=>[0, 2], [:b]=>[1, 3], [:c]=>[4]}) }
1945
2068
  end
1946
-
2069
+
1947
2070
  context 'vector name invalid' do
1948
2071
  before { dv.name = :hello }
1949
2072
  it { expect { dv.group_by :abc }.to raise_error }
@@ -1974,6 +2097,24 @@ describe Daru::Vector do
1974
2097
  end
1975
2098
  end
1976
2099
 
2100
+ context "#sort_by_index" do
2101
+ let(:asc) { vector.sort_by_index }
2102
+ let(:desc) { vector.sort_by_index(ascending: false) }
2103
+
2104
+ context 'numeric vector' do
2105
+ let(:vector) { Daru::Vector.new [11, 13, 12], index: [23, 21, 22] }
2106
+ specify { expect(asc.to_a).to eq [13, 12, 11] }
2107
+ specify { expect(desc.to_a).to eq [11, 12, 13] }
2108
+ end
2109
+
2110
+ context 'mix variable type index' do
2111
+ let(:vector) { Daru::Vector.new [11, Float::NAN, nil],
2112
+ index: [21, 23, 22] }
2113
+ specify { expect(asc.to_a).to eq [11, nil, Float::NAN] }
2114
+ specify { expect(desc.to_a).to eq [Float::NAN, nil, 11] }
2115
+ end
2116
+ end
2117
+
1977
2118
  context '#db_type' do
1978
2119
  it 'is DATE for vector with any date in it' do
1979
2120
  # FIXME: is it sane?.. - zverok
@@ -2003,4 +2144,13 @@ describe Daru::Vector do
2003
2144
  end
2004
2145
  end
2005
2146
 
2147
+ context '#where clause when Nan, nil data value is present' do
2148
+ let(:v) { Daru::Vector.new([1,2,3,Float::NAN, nil]) }
2149
+
2150
+ it 'missing/undefined data in Vector/DataFrame' do
2151
+ expect(v.where(v.lt(4))).to eq(Daru::Vector.new([1,2,3]))
2152
+ expect(v.where(v.lt(3))).to eq(Daru::Vector.new([1,2]))
2153
+ expect(v.where(v.lt(2))).to eq(Daru::Vector.new([1]))
2154
+ end
2155
+ end
2006
2156
  end if mri?