class CsvPivot::PivotTable
Constants
- DEFAULT_OPTIONS
Public Class Methods
new(opts = {})
click to toggle source
# File lib/csv_pivot/pivot_table.rb, line 14 def initialize(opts = {}) p = Proc.new do |array| # the default aggregation method: sum array.map(&:to_i).reduce(0, :+) end @opts = DEFAULT_OPTIONS.merge(opts) @input_path = @opts[:input_path] @input_array = @opts[:input_data] @pivot_rows = @opts[:pivot_rows] @pivot_columns = @opts[:pivot_columns] @pivot_data = @opts[:pivot_data] @sort = @opts[:sort] @headers = @opts[:headers] @column_total = @opts[:column_total] @row_total = @opts[:row_total] @method = @opts[:aggregate_method] || p end
Public Instance Methods
add_column_total(table)
click to toggle source
# File lib/csv_pivot/pivot_table.rb, line 153 def add_column_total(table) i = table[0].length table[0][i] = "Total" table.each_with_index do |row, index| next if index == 0 row[i] = row[1..i].map(&:to_f).reduce(0, :+) end end
add_row_total(table)
click to toggle source
# File lib/csv_pivot/pivot_table.rb, line 162 def add_row_total(table) i = table.length table[i] = ["Total"] table.each_with_index do |row, j| next if j == 0 || j == i row.each_with_index do |value, k| next if k == 0 if table[i][k] table[i][k] += value.to_f else table[i][k] = value.to_f end end end puts table.inspect end
aggregate_data(data_store)
click to toggle source
# File lib/csv_pivot/pivot_table.rb, line 92 def aggregate_data(data_store) data_store.each_value do |value| value[:data] = @method.call(value[:data]) end end
create_data_store()
click to toggle source
# File lib/csv_pivot/pivot_table.rb, line 51 def create_data_store data_store = Hash.new if @headers rows = @input_array[0].index(@pivot_rows) cols = @input_array[0].index(@pivot_columns) data = @input_array[0].index(@pivot_data) else rows = @pivot_rows cols = @pivot_columns data = @pivot_data end @input_array.each_with_index do |row, i| if (@headers && i == 0) then next end if data_store.include? "#{row[rows]}:#{row[cols]}" then data_store["#{row[rows]}:#{row[cols]}"][:data].push(row[data]) else data_store.store("#{row[rows]}:#{row[cols]}", {:row => row[rows], :column => row[cols], :data => [row[data]]} ) end end data_store end
create_data_store_from_csv()
click to toggle source
# File lib/csv_pivot/pivot_table.rb, line 77 def create_data_store_from_csv data_store = Hash.new CSV.foreach(@input_path, :headers => @headers) do |row| if data_store.include? "#{row[@pivot_rows]}:#{row[@pivot_columns]}" then data_store["#{row[@pivot_rows]}:#{row[@pivot_columns]}"][:data].push(row[@pivot_data]) else data_store.store("#{row[@pivot_rows]}:#{row[@pivot_columns]}", {:row => row[@pivot_rows], :column => row[@pivot_columns], :data => [row[@pivot_data]]} ) end end data_store end
create_table(data_store, column_map, row_map)
click to toggle source
# File lib/csv_pivot/pivot_table.rb, line 126 def create_table(data_store, column_map, row_map) pivoted_table = [[]] column_map.each do |key, value| pivoted_table[0][value] = key end row_map.each do |key, value| pivoted_table[value] = [key] end data_store.each_value do |value| row = row_map[value[:row]] column = column_map[value[:column]] pivoted_table[row][column] = value[:data] end pivoted_table[0][0] = @pivot_rows if @headers add_column_total(pivoted_table) if @column_total add_row_total(pivoted_table) if @row_total pivoted_table end
map_columns_and_rows(data_store)
click to toggle source
# File lib/csv_pivot/pivot_table.rb, line 98 def map_columns_and_rows(data_store) column_map = Hash.new row_map = Hash.new col_i = row_i = 1 data_store.each_value do |value| if !column_map.include? value[:column] column_map.store(value[:column], col_i) col_i += 1 end if !row_map.include? value[:row] row_map.store(value[:row], row_i) row_i += 1 end end [column_map, row_map] end
output_csv(pivoted_table, output_file)
click to toggle source
# File lib/csv_pivot/pivot_table.rb, line 145 def output_csv(pivoted_table, output_file) CSV.open(output_file, "w") do |csv| pivoted_table.each do |row| csv << row end end end
pivot()
click to toggle source
# File lib/csv_pivot/pivot_table.rb, line 31 def pivot if @input_path data_store = create_data_store_from_csv else data_store = create_data_store end aggregate_data(data_store) column_map, row_map = map_columns_and_rows(data_store) sort(column_map, row_map) if @sort create_table(data_store, column_map, row_map) end
pivot_to_csv(output_file)
click to toggle source
# File lib/csv_pivot/pivot_table.rb, line 46 def pivot_to_csv(output_file) pivot_table = pivot output_csv(pivot_table, output_file) end
sort(column_map, row_map)
click to toggle source
# File lib/csv_pivot/pivot_table.rb, line 115 def sort(column_map, row_map) sorted_columns = column_map.keys.sort sorted_rows = row_map.keys.sort sorted_columns.each_with_index do |column, index| column_map[column] = index + 1 end sorted_rows.each_with_index do |row, index| row_map[row] = index + 1 end end