daru 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
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?