/// <summary> /// Groups the data by the values in the given column, and computes the given aggregate quantity for each group. /// </summary> /// <typeparam name="T">The type of the aggregate output.</typeparam> /// <param name="groupByColumnName">The name of the column to group by.</param> /// <param name="aggregateColumnName">The name of the column for the aggregate output.</param> /// <param name="aggregator">A function that computes the aggregate quantity.</param> /// <returns>A new data frame containing the requested aggregate values for each group.</returns> /// <remarks> /// <para>The function that computes the aggregate receives a <see cref="FrameView"/> containing /// all the rows in the group. To produce an aggregate result, it can use values in any of /// the columns.</para> /// <para>To produce more than one aggregate value, use <see cref="GroupBy(string, Func{FrameView, IReadOnlyDictionary{string, object}})"/>.</para> /// </remarks> public FrameTable GroupBy <T>(string groupByColumnName, Func <FrameView, T> aggregator, string aggregateColumnName) { if (groupByColumnName == null) { throw new ArgumentNullException(nameof(groupByColumnName)); } if (aggregator == null) { throw new ArgumentNullException(nameof(aggregator)); } if (aggregateColumnName == null) { throw new ArgumentNullException(nameof(aggregateColumnName)); } // Collect the rows into groups. int groupByColumnIndex = GetColumnIndex(groupByColumnName); NamedList groupByColumn = columns[groupByColumnIndex]; NullableDictionary <object, List <int> > groups = FindGroups(groupByColumn); // Form destination columns based on group aggregates. NamedList groupsColumn = NamedList.Create(groupByColumnName, groupByColumn.StorageType); NamedList <T> aggregateColumn = new NamedList <T>(aggregateColumnName); foreach (KeyValuePair <object, List <int> > group in groups) { FrameView values = new FrameView(this.columns, group.Value); T aggregateValue = aggregator(values); aggregateColumn.AddItem(aggregateValue); object groupKey = group.Key; groupsColumn.AddItem(groupKey); } FrameTable result = new FrameTable(groupsColumn, aggregateColumn); return(result); }
internal FrameColumnCollection(FrameView frame) { Debug.Assert(frame != null); this.frame = frame; }
internal FrameColumn(FrameView frame, int c) { this.column = frame.columns[c]; this.map = frame.map; }