code: def agg(self, func, *fields, **name):
          
          if name:
              if len(name) > 1 or 'name' not in name:
                  raise TypeError("Unknown keyword args passed into `agg`: %s"
                                  % name)
              name = name.get('name')
              if not isinstance(name, basestring):
                  raise TypeError("Column names must be strings, not `%s`"
                                  % type(name))
              else:
                  name = name
          elif func.__name__ == '<lambda>':
              name = "lambda%04d" % self.__lambda_num
              self.__lambda_num += 1
              name += "(%s)" % ','.join(fields)
          else:
              name = func.__name__
              name += "(%s)" % ','.join(fields)
  
          aggregated_column = []
  
          if len(fields) > 1:
              for groupkey in self.__grouptable['groupkey']:
                  agg_data = [tuple([row[field] for field in fields])
                              for row in self.__key_to_group_map[groupkey]]
                  aggregated_column.append(func(agg_data))
          elif len(fields) == 1:
              field = fields[0]
              for groupkey in self.__grouptable['groupkey']:
                  agg_data = [row[field]
                              for row in self.__key_to_group_map[groupkey]]
                  aggregated_column.append(func(agg_data))
          else:
              for groupkey in self.__grouptable['groupkey']:
                  agg_data = self.__key_to_group_map[groupkey]
                  aggregated_column.append(func(agg_data))
  
          self.__grouptable[name] = aggregated_column
          return self
docs: Calls the aggregation function `func` on each group in the GroubyTable,
          and leaves the results in a new column with the name of the aggregation
          function.
  
          Call `.agg` with `name='desired_column_name' to choose a column
          name for this aggregation.