func DescTry(spl *etable.Splits, colNm string) error {
	dt := spl.Table()
	if dt == nil {
		return fmt.Errorf("split.DescTry: No splits to aggregate over")
	}
	colIdx, err := dt.ColIdxTry(colNm)
	if err != nil {
		return err
	}
	DescIdx(spl, colIdx)
	return nil
}
DescTry performs aggregation using standard aggregation functions across
all splits, and stores results in the Splits.
Column is specified by name -- returns error for bad column name.
package split
import (
	"fmt"
	"github.com/emer/etable/agg"
	"github.com/emer/etable/etable"
)
func AggIdx(spl *etable.Splits, colIdx int, aggTyp agg.Aggs) *etable.SplitAgg {
	ag := spl.AddAgg(agg.AggsName(aggTyp), colIdx)
	for _, sp := range spl.Splits {
		agv := agg.AggIdx(sp, colIdx, aggTyp)
		ag.Aggs = append(ag.Aggs, agv)
	}
	return ag
}
func Agg(spl *etable.Splits, colNm string, aggTyp agg.Aggs) *etable.SplitAgg {
	dt := spl.Table()
	if dt == nil {
		return nil
	}
	return AggIdx(spl, dt.ColIdx(colNm), aggTyp)
}
func AggTry(spl *etable.Splits, colNm string, aggTyp agg.Aggs) (*etable.SplitAgg, error) {
	dt := spl.Table()
	if dt == nil {
		return nil, fmt.Errorf("split.AggTry: No splits to aggregate over")
	}
	colIdx, err := dt.ColIdxTry(colNm)
	if err != nil {
		return nil, err
	}
	return AggIdx(spl, colIdx, aggTyp), nil
}
func DescIdx(spl *etable.Splits, colIdx int) {
	dt := spl.Table()
	if dt == nil {
		return
	}
	col := dt.Cols[colIdx]
	allAggs := agg.DescAggs
	if col.NumDims() > 1 {  
		allAggs = agg.DescAggsND
	}
	for _, ag := range allAggs {
		AggIdx(spl, colIdx, ag)
	}
}
func Desc(spl *etable.Splits, colNm string) {
	dt := spl.Table()
	if dt == nil {
		return
	}
	DescIdx(spl, dt.ColIdx(colNm))
}