rover-df 0.1.1 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b003d311b623fdd38fee4c6fa76129ad4bba042e8193c1872928cb05085daad3
4
- data.tar.gz: d0c8c04b2a8aec3ea5b7616cbcda61f03a12c96fc8f9a0c7aa29fc898948b759
3
+ metadata.gz: 0a96f5fa610232beb50eb2d22cd87b52627dfda44139e618fb0fa5d82f4d90fa
4
+ data.tar.gz: 899ae175705f7195a994c0bfd19fd021334404d07440f05153c08be5fa08c11b
5
5
  SHA512:
6
- metadata.gz: 8033d8ae9e5fb8c8e767ba68897d37745cc5d35a7a82cb2847e2b1d2c3adf8eeb406914cd47949d8f4c3f21307617ab550f435e7a5c257fe1187ed47dd943829
7
- data.tar.gz: acfdca4ad081e2722c4b5269824de123d26aadab28532837d2bfc717c2ca263f73dc4335963beae654b24d4c17cebbefdcce761a946f391340a306c9ca2a8c9b
6
+ metadata.gz: dc61f769ce5bac5fcda65dcc25fb940f7bf9f81ac168029748b5ccf8bfb896008f0836f9523ca3785e22782dff3f4d8dccc19ae823f944391c47df41fd88b3ec
7
+ data.tar.gz: 5a0c7e5e77233ef8bf7b4df23d711ec22a2e85165715ca330344a0b6cd5bef99e571256496e9c6f6037bf0fc0c771b4e951d91f0a85c17211127649d6e246878
data/CHANGELOG.md CHANGED
@@ -1,3 +1,33 @@
1
+ ## 0.2.4 (2021-06-03)
2
+
3
+ - Added grouping for `std` and `var`
4
+ - Fixed `==` for data frames
5
+ - Fixed error with `first` and `last` for data frames
6
+ - Fixed error with `last` when vector size is smaller than `n`
7
+
8
+ ## 0.2.3 (2021-02-08)
9
+
10
+ - Added `select`, `reject`, and `map!` methods to vectors
11
+
12
+ ## 0.2.2 (2021-01-01)
13
+
14
+ - Added line, pie, area, and bar charts
15
+ - Added `|` and `^` for vectors
16
+ - Fixed typecasting with `map`
17
+
18
+ ## 0.2.1 (2020-11-23)
19
+
20
+ - Added `plot` method to data frames
21
+ - Improved error message when too few headers
22
+
23
+ ## 0.2.0 (2020-08-17)
24
+
25
+ - Added `numeric?` and `zip` methods to vectors
26
+ - Changed group calculations to return a data frame instead of a hash
27
+ - Changed `each_row` to return enumerator
28
+ - Improved inspect
29
+ - Fixed `any?`, `all?`, and `uniq` for boolean vectors
30
+
1
31
  ## 0.1.1 (2020-06-10)
2
32
 
3
33
  - Added methods and options for types
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2020 Andrew Kane
1
+ Copyright (c) 2020-2021 Andrew Kane
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -4,7 +4,9 @@ Simple, powerful data frames for Ruby
4
4
 
5
5
  :mountain: Designed for data exploration and machine learning, and powered by [Numo](https://github.com/ruby-numo/numo-narray)
6
6
 
7
- [![Build Status](https://travis-ci.org/ankane/rover.svg?branch=master)](https://travis-ci.org/ankane/rover)
7
+ :evergreen_tree: Uses [Vega](https://github.com/ankane/vega) for visualization
8
+
9
+ [![Build Status](https://github.com/ankane/rover/workflows/build/badge.svg?branch=master)](https://github.com/ankane/rover/actions)
8
10
 
9
11
  ## Installation
10
12
 
@@ -121,30 +123,53 @@ df[1..3]
121
123
  df[[1, 4, 5]]
122
124
  ```
123
125
 
126
+ Iterate over rows
127
+
128
+ ```ruby
129
+ df.each_row { |row| ... }
130
+ ```
131
+
132
+ Iterate over a column
133
+
134
+ ```ruby
135
+ df[:a].each { |item| ... }
136
+ # or
137
+ df[:a].each_with_index { |item, index| ... }
138
+ ```
139
+
124
140
  ## Filtering
125
141
 
126
142
  Filter on a condition
127
143
 
128
144
  ```ruby
145
+ df[df[:a] == 100]
146
+ df[df[:a] != 100]
129
147
  df[df[:a] > 100]
148
+ df[df[:a] >= 100]
149
+ df[df[:a] < 100]
150
+ df[df[:a] <= 100]
130
151
  ```
131
152
 
132
- And
153
+ In
133
154
 
134
155
  ```ruby
135
- df[df[:a] > 100 & df[:b] == "one"]
156
+ df[df[:a].in?([1, 2, 3])]
157
+ df[df[:a].in?(1..3)]
158
+ df[df[:a].in?(["a", "b", "c"])]
136
159
  ```
137
160
 
138
- Or
161
+ Not in
139
162
 
140
163
  ```ruby
141
- df[df[:a] > 100 | df[:b] == "one"]
164
+ df[!df[:a].in?([1, 2, 3])]
142
165
  ```
143
166
 
144
- Not
167
+ And, or, and exclusive or
145
168
 
146
169
  ```ruby
147
- df[df[:a] != 100]
170
+ df[(df[:a] > 100) & (df[:b] == "one")] # and
171
+ df[(df[:a] > 100) | (df[:b] == "one")] # or
172
+ df[(df[:a] > 100) ^ (df[:b] == "one")] # xor
148
173
  ```
149
174
 
150
175
  ## Operations
@@ -170,6 +195,8 @@ df[:a].median
170
195
  df[:a].percentile(90)
171
196
  df[:a].min
172
197
  df[:a].max
198
+ df[:a].std
199
+ df[:a].var
173
200
  ```
174
201
 
175
202
  Count occurrences
@@ -204,6 +231,26 @@ Multiple groups
204
231
  df.group([:a, :b]).count
205
232
  ```
206
233
 
234
+ ## Visualization
235
+
236
+ Add [Vega](https://github.com/ankane/vega) to your application’s Gemfile:
237
+
238
+ ```ruby
239
+ gem 'vega'
240
+ ```
241
+
242
+ And use:
243
+
244
+ ```ruby
245
+ df.plot(:a, :b)
246
+ ```
247
+
248
+ Specify the chart type (`line`, `pie`, `column`, `bar`, `area`, or `scatter`)
249
+
250
+ ```ruby
251
+ df.plot(:a, :b, type: "pie")
252
+ ```
253
+
207
254
  ## Updating Data
208
255
 
209
256
  Add a new column
@@ -228,6 +275,14 @@ df[:a][0..2] = 1
228
275
  df[:a][0..2] = [1, 2, 3]
229
276
  ```
230
277
 
278
+ Update all elements
279
+
280
+ ```ruby
281
+ df[:a] = df[:a].map { |v| v.gsub("a", "b") }
282
+ # or
283
+ df[:a].map! { |v| v.gsub("a", "b") }
284
+ ```
285
+
231
286
  Update elements matching a condition
232
287
 
233
288
  ```ruby
@@ -340,7 +395,7 @@ df.to_csv
340
395
 
341
396
  ## Types
342
397
 
343
- Pass column types when creating a data frame
398
+ You can specify column types when creating a data frame
344
399
 
345
400
  ```ruby
346
401
  Rover::DataFrame.new(data, types: {"a" => :int, "b" => :float})
data/lib/rover.rb CHANGED
@@ -11,12 +11,12 @@ module Rover
11
11
  class << self
12
12
  def read_csv(path, types: nil, **options)
13
13
  require "csv"
14
- csv_to_df(CSV.read(path, **csv_options(options)), types: types)
14
+ csv_to_df(CSV.read(path, **csv_options(options)), types: types, headers: options[:headers])
15
15
  end
16
16
 
17
17
  def parse_csv(str, types: nil, **options)
18
18
  require "csv"
19
- csv_to_df(CSV.parse(str, **csv_options(options)), types: types)
19
+ csv_to_df(CSV.parse(str, **csv_options(options)), types: types, headers: options[:headers])
20
20
  end
21
21
 
22
22
  private
@@ -28,7 +28,11 @@ module Rover
28
28
  options
29
29
  end
30
30
 
31
- def csv_to_df(table, types: nil)
31
+ def csv_to_df(table, types: nil, headers: nil)
32
+ if headers && headers.size < table.headers.size
33
+ raise ArgumentError, "Expected #{table.headers.size} headers, got #{headers.size}"
34
+ end
35
+
32
36
  table.by_col!
33
37
  data = {}
34
38
  table.each do |k, v|
@@ -72,6 +72,7 @@ module Rover
72
72
  # multiple columns
73
73
  df = DataFrame.new
74
74
  where.each do |k|
75
+ check_column(k, true)
75
76
  df[k] = @vectors[k]
76
77
  end
77
78
  df
@@ -81,8 +82,9 @@ module Rover
81
82
  end
82
83
  end
83
84
 
84
- # return each row as a hash
85
85
  def each_row
86
+ return enum_for(:each_row) unless block_given?
87
+
86
88
  size.times do |i|
87
89
  yield @vectors.map { |k, v| [k, v[i]] }.to_h
88
90
  end
@@ -161,7 +163,7 @@ module Rover
161
163
  last(n)
162
164
  end
163
165
 
164
- def first(n = nil)
166
+ def first(n = 1)
165
167
  new_vectors = {}
166
168
  @vectors.each do |k, v|
167
169
  new_vectors[k] = v.first(n)
@@ -169,7 +171,7 @@ module Rover
169
171
  DataFrame.new(new_vectors)
170
172
  end
171
173
 
172
- def last(n = nil)
174
+ def last(n = 1)
173
175
  new_vectors = {}
174
176
  @vectors.each do |k, v|
175
177
  new_vectors[k] = v.last(n)
@@ -236,7 +238,12 @@ module Rover
236
238
  # for IRuby
237
239
  def to_html
238
240
  require "iruby"
239
- IRuby::HTML.table(to_h)
241
+ if size > 7
242
+ # pass 8 rows so maxrows is applied
243
+ IRuby::HTML.table((self[0..4] + self[-4..-1]).to_h, maxrows: 7)
244
+ else
245
+ IRuby::HTML.table(to_h)
246
+ end
240
247
  end
241
248
 
242
249
  # TODO handle long text better
@@ -247,18 +254,19 @@ module Rover
247
254
  line_start = 0
248
255
  spaces = 2
249
256
 
257
+ summarize = size >= 30
258
+
250
259
  @vectors.each do |k, v|
251
- v = v.first(5).to_a
260
+ v = summarize ? v.first(5).to_a + ["..."] + v.last(5).to_a : v.to_a
252
261
  width = ([k] + v).map(&:to_s).map(&:size).max
253
262
  width = 3 if width < 3
254
263
 
255
264
  if lines.empty? || lines[-2].map { |l| l.size + spaces }.sum + width > 120
256
265
  line_start = lines.size
257
266
  lines << []
258
- [size, 5].min.times do |i|
267
+ v.size.times do |i|
259
268
  lines << []
260
269
  end
261
- lines << [] if size > 5
262
270
  lines << []
263
271
  end
264
272
 
@@ -266,7 +274,6 @@ module Rover
266
274
  v.each_with_index do |v2, i|
267
275
  lines[line_start + 1 + i] << "%#{width}s" % v2.to_s
268
276
  end
269
- lines[line_start + 6] << "%#{width}s" % "..." if size > 5
270
277
  end
271
278
 
272
279
  lines.pop
@@ -290,11 +297,11 @@ module Rover
290
297
  dup.sort_by!(&block)
291
298
  end
292
299
 
293
- def group(columns)
294
- Group.new(self, columns)
300
+ def group(*columns)
301
+ Group.new(self, columns.flatten)
295
302
  end
296
303
 
297
- [:max, :min, :median, :mean, :percentile, :sum].each do |name|
304
+ [:max, :min, :median, :mean, :percentile, :sum, :std, :var].each do |name|
298
305
  define_method(name) do |column, *args|
299
306
  check_column(column)
300
307
  self[column].send(name, *args)
@@ -353,7 +360,89 @@ module Rover
353
360
  def ==(other)
354
361
  size == other.size &&
355
362
  keys == other.keys &&
356
- keys.all? { |k| self[k] == other[k] }
363
+ keys.all? { |k| self[k].to_numo == other[k].to_numo }
364
+ end
365
+
366
+ def plot(x = nil, y = nil, type: nil)
367
+ require "vega"
368
+
369
+ raise ArgumentError, "Must specify columns" if keys.size != 2 && (!x || !y)
370
+ x ||= keys[0]
371
+ y ||= keys[1]
372
+ type ||= begin
373
+ if self[x].numeric? && self[y].numeric?
374
+ "scatter"
375
+ elsif types[x] == :object && self[y].numeric?
376
+ "column"
377
+ else
378
+ raise "Cannot determine type. Use the type option."
379
+ end
380
+ end
381
+ data = self[[x, y]]
382
+
383
+ case type
384
+ when "line", "area"
385
+ x_type =
386
+ if data[x].numeric?
387
+ "quantitative"
388
+ elsif data[x].all? { |v| v.is_a?(Date) || v.is_a?(Time) }
389
+ "temporal"
390
+ else
391
+ "nominal"
392
+ end
393
+
394
+ scale = x_type == "temporal" ? {type: "utc"} : {}
395
+
396
+ Vega.lite
397
+ .data(data)
398
+ .mark(type: type, tooltip: true, interpolate: "cardinal", point: {size: 60})
399
+ .encoding(
400
+ x: {field: x, type: x_type, scale: scale},
401
+ y: {field: y, type: "quantitative"}
402
+ )
403
+ .config(axis: {labelFontSize: 12})
404
+ when "pie"
405
+ Vega.lite
406
+ .data(data)
407
+ .mark(type: "arc", tooltip: true)
408
+ .encoding(
409
+ color: {field: x, type: "nominal", sort: "none", axis: {title: nil}, legend: {labelFontSize: 12}},
410
+ theta: {field: y, type: "quantitative"}
411
+ )
412
+ .view(stroke: nil)
413
+ when "column"
414
+ Vega.lite
415
+ .data(data)
416
+ .mark(type: "bar", tooltip: true)
417
+ .encoding(
418
+ # TODO determine label angle
419
+ x: {field: x, type: "nominal", sort: "none", axis: {labelAngle: 0}},
420
+ y: {field: y, type: "quantitative"}
421
+ )
422
+ .config(axis: {labelFontSize: 12})
423
+ when "bar"
424
+ Vega.lite
425
+ .data(data)
426
+ .mark(type: "bar", tooltip: true)
427
+ .encoding(
428
+ # TODO determine label angle
429
+ y: {field: x, type: "nominal", sort: "none", axis: {labelAngle: 0}},
430
+ x: {field: y, type: "quantitative"}
431
+ )
432
+ .config(axis: {labelFontSize: 12})
433
+ when "scatter"
434
+ Vega.lite
435
+ .data(data)
436
+ .mark(type: "circle", tooltip: true)
437
+ .encoding(
438
+ x: {field: x, type: "quantitative", scale: {zero: false}},
439
+ y: {field: y, type: "quantitative", scale: {zero: false}},
440
+ size: {value: 60}
441
+ )
442
+ .config(axis: {labelFontSize: 12})
443
+ else
444
+ raise ArgumentError, "Invalid type: #{type}"
445
+ end
357
446
  end
358
447
 
359
448
  private
@@ -418,8 +507,20 @@ module Rover
418
507
  raise ArgumentError, "Missing keys: #{missing_keys.join(", ")}" if missing_keys.any?
419
508
  end
420
509
 
421
- def check_column(key)
422
- raise ArgumentError, "Missing column: #{key}" unless include?(key)
510
+ # TODO in 0.3.0
511
+ # always use did_you_mean
512
+ def check_column(key, did_you_mean = false)
513
+ unless include?(key)
514
+ if did_you_mean
515
+ if RUBY_VERSION.to_f >= 2.6
516
+ raise KeyError.new("Missing column: #{key}", receiver: self, key: key)
517
+ else
518
+ raise KeyError.new("Missing column: #{key}")
519
+ end
520
+ else
521
+ raise ArgumentError, "Missing column: #{key}"
522
+ end
523
+ end
423
524
  end
424
525
 
425
526
  def to_vector(v, size: nil, type: nil)
data/lib/rover/group.rb CHANGED
@@ -2,16 +2,23 @@ module Rover
2
2
  class Group
3
3
  def initialize(df, columns)
4
4
  @df = df
5
- @columns = Array(columns)
5
+ @columns = columns
6
6
  end
7
7
 
8
- [:count, :max, :min, :mean, :median, :percentile, :sum].each do |name|
8
+ def group(*columns)
9
+ Group.new(@df, @columns + columns.flatten)
10
+ end
11
+
12
+ [:count, :max, :min, :mean, :median, :percentile, :sum, :std, :var].each do |name|
9
13
  define_method(name) do |*args|
10
- result = {}
14
+ n = [name, args.first].compact.join("_")
15
+
16
+ rows = []
11
17
  grouped_dfs.each do |k, df|
12
- result[k] = df.send(name, *args)
18
+ rows << k.merge(n => df.send(name, *args))
13
19
  end
14
- result
20
+
21
+ DataFrame.new(rows)
15
22
  end
16
23
  end
17
24
 
@@ -26,21 +33,15 @@ module Rover
26
33
  raise ArgumentError, "Missing keys: #{missing_keys.join(", ")}" if missing_keys.any?
27
34
 
28
35
  groups = Hash.new { |hash, key| hash[key] = [] }
29
- if @columns.size == 1
30
- @df[@columns.first].each_with_index do |v, i|
31
- groups[v] << i
32
- end
33
- else
34
- i = 0
35
- @df.each_row do |row|
36
- groups[@columns.map { |c| row[c] }] << i
37
- i += 1
38
- end
36
+ i = 0
37
+ @df.each_row do |row|
38
+ groups[row.slice(*@columns)] << i
39
+ i += 1
39
40
  end
40
41
 
41
42
  result = {}
42
- groups.each do |k, indexes|
43
- result[k] = @df[indexes]
43
+ groups.keys.each do |k|
44
+ result[k] = @df[groups[k]]
44
45
  end
45
46
  result
46
47
  end
data/lib/rover/vector.rb CHANGED
@@ -44,6 +44,10 @@ module Rover
44
44
  a
45
45
  end
46
46
 
47
+ def numeric?
48
+ ![:object, :bool].include?(type)
49
+ end
50
+
47
51
  def size
48
52
  @data.size
49
53
  end
@@ -51,7 +55,7 @@ module Rover
51
55
  alias_method :count, :size
52
56
 
53
57
  def uniq
54
- Vector.new(@data.to_a.uniq)
58
+ Vector.new(to_a.uniq)
55
59
  end
56
60
 
57
61
  def missing
@@ -87,11 +91,11 @@ module Rover
87
91
  @data[k] = v
88
92
  end
89
93
 
90
- %w(+ - * / % ** &).each do |op|
94
+ %w(+ - * / % ** & | ^).each do |op|
91
95
  define_method(op) do |other|
92
96
  other = other.to_numo if other.is_a?(Vector)
93
97
  # TODO better logic
94
- if @data.is_a?(Numo::RObject)
98
+ if @data.is_a?(Numo::RObject) && !other.is_a?(Numo::RObject)
95
99
  map { |v| v.send(op, other) }
96
100
  else
97
101
  Vector.new(@data.send(op, other))
@@ -157,9 +161,22 @@ module Rover
157
161
  end
158
162
 
159
163
  def map(&block)
160
- mapped = @data.map(&block)
161
- mapped = mapped.to_a if mapped.is_a?(Numo::RObject) # re-evaluate cast
162
- Vector.new(mapped)
164
+ # convert to Ruby first to cast properly
165
+ # https://github.com/ruby-numo/numo-narray/issues/181
166
+ Vector.new(@data.to_a.map(&block))
167
+ end
168
+
169
+ def map!(&block)
170
+ @data = cast_data(@data.to_a.map(&block))
171
+ self
172
+ end
173
+
174
+ def select(&block)
175
+ Vector.new(@data.to_a.select(&block))
176
+ end
177
+
178
+ def reject(&block)
179
+ Vector.new(@data.to_a.reject(&block))
163
180
  end
164
181
 
165
182
  def tally
@@ -226,11 +243,15 @@ module Rover
226
243
  end
227
244
 
228
245
  def all?(&block)
229
- @data.to_a.all?(&block)
246
+ to_a.all?(&block)
230
247
  end
231
248
 
232
249
  def any?(&block)
233
- @data.to_a.any?(&block)
250
+ to_a.any?(&block)
251
+ end
252
+
253
+ def zip(other, &block)
254
+ to_a.zip(other.to_a, &block)
234
255
  end
235
256
 
236
257
  def first(n = 1)
@@ -242,7 +263,11 @@ module Rover
242
263
  end
243
264
 
244
265
  def last(n = 1)
245
- Vector.new(@data[-n..-1])
266
+ if n >= size
267
+ Vector.new(@data)
268
+ else
269
+ Vector.new(@data[-n..-1])
270
+ end
246
271
  end
247
272
 
248
273
  def take(n)
@@ -298,7 +323,12 @@ module Rover
298
323
  # for IRuby
299
324
  def to_html
300
325
  require "iruby"
301
- IRuby::HTML.table(to_a)
326
+ if size > 7
327
+ # pass 8 rows so maxrows is applied
328
+ IRuby::HTML.table(first(4).to_a + last(4).to_a, maxrows: 7)
329
+ else
330
+ IRuby::HTML.table(to_a)
331
+ end
302
332
  end
303
333
 
304
334
  private
data/lib/rover/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rover
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.4"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rover-df
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-10 00:00:00.000000000 Z
11
+ date: 2021-06-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: numo-narray
@@ -16,100 +16,16 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.9.1.7
19
+ version: 0.9.1.9
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.9.1.7
27
- - !ruby/object:Gem::Dependency
28
- name: bundler
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: rake
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: minitest
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '5'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '5'
69
- - !ruby/object:Gem::Dependency
70
- name: activerecord
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '5'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '5'
83
- - !ruby/object:Gem::Dependency
84
- name: sqlite3
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: iruby
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
- description:
112
- email: andrew@chartkick.com
26
+ version: 0.9.1.9
27
+ description:
28
+ email: andrew@ankane.org
113
29
  executables: []
114
30
  extensions: []
115
31
  extra_rdoc_files: []
@@ -127,7 +43,7 @@ homepage: https://github.com/ankane/rover
127
43
  licenses:
128
44
  - MIT
129
45
  metadata: {}
130
- post_install_message:
46
+ post_install_message:
131
47
  rdoc_options: []
132
48
  require_paths:
133
49
  - lib
@@ -142,8 +58,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
142
58
  - !ruby/object:Gem::Version
143
59
  version: '0'
144
60
  requirements: []
145
- rubygems_version: 3.1.2
146
- signing_key:
61
+ rubygems_version: 3.2.3
62
+ signing_key:
147
63
  specification_version: 4
148
64
  summary: Simple, powerful data frames for Ruby
149
65
  test_files: []