Aggregate our groups
(aggs ...AggregateBy)
| 137 | |
| 138 | // Aggregate our groups |
| 139 | func (g *Groups) Aggregate(aggs ...AggregateBy) (*DataTable, error) { |
| 140 | if g == nil { |
| 141 | return nil, ErrNoGroups |
| 142 | } |
| 143 | |
| 144 | if g.dt == nil { |
| 145 | return nil, ErrNilDatatable |
| 146 | } |
| 147 | |
| 148 | // check cols |
| 149 | series := make(map[string]serie.Serie) |
| 150 | for _, agg := range aggs { |
| 151 | col := g.dt.Column(agg.Field) |
| 152 | if col == nil { |
| 153 | err := errors.Errorf("column '%s' not found", agg.Field) |
| 154 | return nil, errors.Wrap(err, ErrColumnNotFound.Error()) |
| 155 | } |
| 156 | switch agg.Type { |
| 157 | case Avg, Count, CountDistinct, Cusum, Max, Min, Median, Stddev, Sum, Variance: |
| 158 | series[agg.Field] = col.(*column).serie |
| 159 | default: |
| 160 | return nil, ErrUnknownAgg |
| 161 | } |
| 162 | } |
| 163 | |
| 164 | out := New(g.dt.name) |
| 165 | |
| 166 | // create columns |
| 167 | for _, by := range g.by { |
| 168 | typ := by.Type |
| 169 | if len(typ) == 0 { |
| 170 | typ = Raw |
| 171 | } |
| 172 | if err := out.AddColumn(by.Name, typ); err != nil { |
| 173 | err = errors.Wrapf(err, "can't add column '%s'", by.Name) |
| 174 | return nil, errors.Wrap(err, ErrCantAddColumn.Error()) |
| 175 | } |
| 176 | } |
| 177 | for _, agg := range aggs { |
| 178 | name := agg.As |
| 179 | if len(name) == 0 { |
| 180 | name = fmt.Sprintf("%s %s", agg.Type, agg.Field) |
| 181 | } |
| 182 | typ := Float64 |
| 183 | switch agg.Type { |
| 184 | case Count, CountDistinct: |
| 185 | typ = Int64 |
| 186 | default: |
| 187 | } |
| 188 | if err := out.AddColumn(name, typ); err != nil { |
| 189 | err = errors.Wrapf(err, "can't add column '%s'", name) |
| 190 | return nil, errors.Wrap(err, ErrCantAddColumn.Error()) |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | // aggregate the series |
| 195 | for _, group := range g.groups { |
| 196 | values := make([]interface{}, 0, len(group.Buckets)+len(aggs)) |