PivotTable { public static Table pivot( Table table, CategoricalColumn<?> column1, CategoricalColumn<?> column2, NumericColumn<?> values, AggregateFunction<?, ?> aggregateFunction) { TableSliceGroup tsg = table.splitOn(column1); Table pivotTable = Table.create("Pivot: " + column1.name() + " x " + column2.name()); pivotTable.addColumns(column1.type().create(column1.name())); List<String> valueColumnNames = getValueColumnNames(table, column2); for (String colName : valueColumnNames) { pivotTable.addColumns(DoubleColumn.create(colName)); } int valueIndex = table.columnIndex(column2); int keyIndex = table.columnIndex(column1); String key; for (TableSlice slice : tsg.getSlices()) { key = String.valueOf(slice.get(0, keyIndex)); pivotTable.column(0).appendCell(key); Map<String, Double> valueMap = getValueMap(column1, column2, values, valueIndex, slice, aggregateFunction); for (String columnName : valueColumnNames) { Double aDouble = valueMap.get(columnName); NumericColumn<?> pivotValueColumn = pivotTable.numberColumn(columnName); if (aDouble == null) { pivotValueColumn.appendMissing(); } else { pivotValueColumn.appendObj(aDouble); } } } return pivotTable; }  static Table pivot(
      Table table,
      CategoricalColumn<?> column1,
      CategoricalColumn<?> column2,
      NumericColumn<?> values,
      AggregateFunction<?, ?> aggregateFunction);  }
@Test public void pivot() throws Exception { Table t = Table.read() .csv(CsvReadOptions.builder("../data/bush.csv").missingValueIndicator(":").build()); t.addColumns(t.dateColumn("date").year()); Table pivot = PivotTable.pivot( t, t.categoricalColumn("who"), t.categoricalColumn("date year"), t.numberColumn("approval"), AggregateFunctions.mean); assertTrue(pivot.columnNames().contains("who")); assertTrue(pivot.columnNames().contains("2001")); assertTrue(pivot.columnNames().contains("2002")); assertTrue(pivot.columnNames().contains("2003")); assertTrue(pivot.columnNames().contains("2004")); assertEquals(6, pivot.rowCount()); }