Skip to content

Instantly share code, notes, and snippets.

@s-shin
Created February 17, 2016 04:58
Show Gist options
  • Save s-shin/6036a7bae7b77790d370 to your computer and use it in GitHub Desktop.
Save s-shin/6036a7bae7b77790d370 to your computer and use it in GitHub Desktop.
car data.tsv | ruby stacked-graph-transformer.rb
class StackedGraphTransformer
# @param [IO] io
def initialize(io)
@io = io
end
def gets_tsv
(line = @io.gets) ? line.chomp.split("\t") : nil
end
def each(&block)
group_title, *_ = gets_tsv
num_one_group = nil
first_group = nil
titles = [group_title]
cols = []
loop do
group, main, *subs, val = gets_tsv
break if group.nil?
first_group ||= group
if first_group === group
fmt = '%s'
fmt << (subs.empty? ? '' : ' (%s)')
titles << (fmt % [main, subs.join(", ")])
elsif num_one_group.nil?
block.call(titles)
num_one_group = cols.size
end
if num_one_group === cols.size
block.call(cols)
cols = []
end
cols << group if cols.empty?
cols << val
end
block.call(cols) unless cols.empty?
end
end
if ARGV[0] == "--test"
require 'test/unit/assertions'
include Test::Unit::Assertions
result = []
StackedGraphTransformer.new(Object::DATA).each {|cols| result << cols}
assert_equal [
['date', '_ (PC)', '_ (SP)', 'facebook (PC)', 'facebook (SP)', 'twitter (PC)', 'twitter (SP)'],
['2016-02-01', 1, 2, 3, 4, 5, 6].map(&:to_s),
['2016-02-02', 11, 12, 13, 14, 15, 16].map(&:to_s),
], result
puts "OK"
else
StackedGraphTransformer.new($stdin).each do |cols|
puts cols.join("\t")
end
end
__END__
date sns device num
2016-02-01 _ PC 1
2016-02-01 _ SP 2
2016-02-01 facebook PC 3
2016-02-01 facebook SP 4
2016-02-01 twitter PC 5
2016-02-01 twitter SP 6
2016-02-02 _ PC 11
2016-02-02 _ SP 12
2016-02-02 facebook PC 13
2016-02-02 facebook SP 14
2016-02-02 twitter PC 15
2016-02-02 twitter SP 16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment