Parent

Included Modules

Files

Ruport::Data::Grouping

Overview

This class implements a grouping data structure for Ruport. A grouping is a collection of groups. It allows you to group the data in a table by one or more columns that you specify.

The data for a grouping is a hash of groups, keyed on each unique data point from the grouping column.

Attributes

data[RW]

The grouping's data

grouped_by[R]

The name of the column used to group the data

Public Class Methods

new(data={},options={}) click to toggle source

Creates a new Grouping based on the supplied options.

Valid options:

:by

A column name or array of column names that the data will be grouped on.

:order

Determines the iteration and presentation order of a Grouping object. Set to :name to order by Group names. You can also provide a lambda which will be passed Group objects, and use semantics similar to Enumerable#group_by

Examples:

table = [[1,2,3],[4,5,6],[1,1,2]].to_table(%w[a b c])

# unordered 
grouping = Grouping.new(table, :by => "a")

# ordered by group name
grouping = Grouping.new(table, :by => "a", :order => :name)

# ordered by group size
grouping = Grouping.new(table, :by => "a", 
                               :order => lambda { |g| g.size } )
# File lib/ruport/data/grouping.rb, line 164
def initialize(data={},options={})
  if data.kind_of?(Hash)
    @grouped_by = data[:by]
    @order = data[:order] 
    @data = {}
  else
    @grouped_by = options[:by]    
    @order = options[:order]
    cols = Array(options[:by]).dup
    @data = data.to_group.send(:grouped_data, cols.shift)
    cols.each do |col|
      @data.each do |name,group|
        group.send(:create_subgroups, col)
      end
    end    
  end
end

Public Instance Methods

/(name) click to toggle source
Alias for: subgrouping
<<(group) click to toggle source

Used to add extra data to the Grouping. group should be a Group.

Example:

table = [[1,2,3],[4,5,6]].to_table(%w[a b c])

grouping = Grouping.new(table, :by => "a")

group = Group.new :name => 7,
                  :data => [[8,9]], 
                  :column_names => %w[b c]

grouping << group
# File lib/ruport/data/grouping.rb, line 245
def <<(group)        
  if data.has_key? group.name
    raise(ArgumentError, "Group '#{group.name}' exists!") 
  end
  @data.merge!({ group.name => group })
end
Also aliased as: append
[](name) click to toggle source

Allows Hash-like indexing of the grouping data.

Examples:

my_grouping["foo"]
# File lib/ruport/data/grouping.rb, line 194
def [](name)
  @data[name] or 
    raise(IndexError,"Group Not Found")
end
append(group) click to toggle source
Alias for: <<
each() click to toggle source

Iterates through the Grouping, yielding each group name and Group object

# File lib/ruport/data/grouping.rb, line 201
def each 
  if @order.respond_to?(:call) 
    @data.sort_by { |n,g| @order[g] }.each { |n,g| yield(n,g) }
  elsif @order == :name
    @data.sort_by { |n,g| n }.each { |name,group| yield(name,group) } 
  else
    @data.each { |name,group| yield(name,group) }
  end
end
method_missing(id,*args) click to toggle source

Provides a shortcut for the as() method by converting a call to to_format_name into a call to as(:format_name).

# File lib/ruport/data/grouping.rb, line 367
def method_missing(id,*args)
  return as($1.to_sym,*args) if id.to_s =~ /^to_(.*)/ 
  super
end
sigma(column=nil) click to toggle source

Calculates sums. If a column name or index is given, it will try to convert each element of that column to an integer or float and add them together. The sum is calculated across all groups in the grouping.

If a block is given, it yields each Record in each Group so that you can do your own calculation.

Example:

table = [[1,2,3],[3,4,5],[5,6,7]].to_table(%w[col1 col2 col3])
grouping = Grouping(table, :by => "col1")
grouping.sigma("col2") #=> 12
grouping.sigma(0)      #=> 12
grouping.sigma { |r| r.col2 + r.col3 } #=> 27
grouping.sigma { |r| r.col2 + 1 } #=> 15
# File lib/ruport/data/grouping.rb, line 329
def sigma(column=nil)
  inject(0) do |s, (group_name, group)|
    if column
      s + group.sigma(column)
    else
      s + group.sigma do |r|
        yield(r)
      end
    end
  end
end
Also aliased as: sum
sort_grouping_by(type=nil,&block) click to toggle source

Returns a new grouping with the specified sort order. You can sort by Group name or an arbitrary block

by_name = grouping.sort_grouping_by(:name) 
by_size = grouping.sort_grouping_by { |g| g.size }
# File lib/ruport/data/grouping.rb, line 217
def sort_grouping_by(type=nil,&block)
  a = Grouping.new(:by => @grouped_by, :order => type || block)
  each { |n,g| a << g }
  return a
end
sort_grouping_by!(type=nil,&block) click to toggle source

Applies the specified sort order to an existing Grouping object.

grouping.sort_grouping_by!(:name)
grouping.sort_grouping_by! { |g| g.size }
# File lib/ruport/data/grouping.rb, line 227
def sort_grouping_by!(type=nil,&block)
  @order = type || block
end
subgrouping(name) click to toggle source

Provides access to the subgroups of a particular group in the Grouping. Supply the name of a group and it returns a Grouping created from the subgroups of the group.

# File lib/ruport/data/grouping.rb, line 258
def subgrouping(name)
  grouping = dup
  grouping.send(:data=, @data[name].subgroups)
  return grouping
end
Also aliased as: /
sum(column=nil) click to toggle source
Alias for: sigma
summary(field,procs) click to toggle source

Useful for creating basic summaries from Grouping objects. Takes a field to summarize on, and then for each group, runs the specified procs and returns the results as a Table.

The following example would show for each date group, the sum for the attributes or methods :opened and :closed and order them by the :order array.

If :order is not specified, you cannot depend on predictable column order.

grouping.summary :date,
  :opened => lambda { |g| g.sigma(:opened) },
  :closed => lambda { |g| g.sigma(:closed) },
  :order => [:date,:opened,:closed]
# File lib/ruport/data/grouping.rb, line 282
def summary(field,procs)     
  if procs[:order].kind_of?(Array)
    cols = procs.delete(:order) 
  else 
    cols = procs.keys + [field]   
  end
  expected = Table(cols) { |t|
    each do |name,group|
      t << procs.inject({field => name}) do |s,r|
        s.merge(r[0] => r[1].call(group))
      end 
    end
    t.data.reorder(cols)     
  }   
end
to_s() click to toggle source

Uses Ruport's built-in text formatter to render this Grouping

Example:

table = [[1,2,3],[4,5,6]].to_table(%w[a b c])

grouping = Grouping.new(table, :by => "a")

puts grouping.to_s
# File lib/ruport/data/grouping.rb, line 308
def to_s
  as(:text)
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.