mirror of
https://github.com/johnkerl/miller.git
synced 2026-07-17 16:38:54 +00:00
* stats1: add rank accumulator (#383) Adds `mlr stats1 -a rank` for standard competition ranking (1,2,2,4,...) on pre-sorted data, most useful with -s for a rank on every record. * stats1: make rank order-independent by default, add --rank-sorted opt-in fast path The rank accumulator previously only compared each value to the immediately preceding record, silently giving wrong ranks for non-adjacent duplicates (e.g. unsorted input, or interleaved -g groups). Default to correctly computing standard competition rank from all values seen so far (order-independent, buffers values, same approach as percentile accumulators). Add --rank-sorted for callers who can promise sorted input and want the previous O(1)-space streaming behavior instead. * Revert "stats1: make rank order-independent by default, add --rank-sorted opt-in fast path" This reverts commitaa45a591fe. * Revert "stats1: add rank accumulator (#383)" This reverts commit96deed048a. * Add mlr rank verb (#383) Reverts the earlier stats1 -a rank / --rank-sorted approach: stats1 is a reduce verb (many records -> one summary record per group) and rank is a per-record annotator, so it never fit cleanly there -- it needed stats1's -s iterative-stats escape hatch just to be useful, plus a bolted-on sorted/unsorted split. mlr rank is a dedicated verb modeled on mlr fraction: -f fields to rank, -g optional group-by, output field <f>_rank. By default it's a two-pass algorithm (buffers input, like fraction does) giving standard competition rank (1,2,2,4,...) that's correct regardless of input order. --sorted opts into a single-pass, O(1)-space streaming alternative for callers who can promise pre-sorted input (e.g. via 'mlr sort' first). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * Regenerate docs/man pages after merging main (sparkline verb) --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
158 lines
3.2 KiB
Go
158 lines
3.2 KiB
Go
package transformers
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/johnkerl/miller/v6/pkg/colorizer"
|
|
"github.com/johnkerl/miller/v6/pkg/lib"
|
|
)
|
|
|
|
var TRANSFORMER_LOOKUP_TABLE = []TransformerSetup{
|
|
AltkvSetup,
|
|
BarSetup,
|
|
BootstrapSetup,
|
|
CaseSetup,
|
|
CatSetup,
|
|
CheckSetup,
|
|
CleanWhitespaceSetup,
|
|
CountDistinctSetup,
|
|
CountSetup,
|
|
CountSimilarSetup,
|
|
CutSetup,
|
|
DecimateSetup,
|
|
DescribeSetup,
|
|
FillDownSetup,
|
|
FillEmptySetup,
|
|
FilterSetup,
|
|
FlattenSetup,
|
|
FormatValuesSetup,
|
|
FractionSetup,
|
|
GapSetup,
|
|
GrepSetup,
|
|
GroupBySetup,
|
|
GroupLikeSetup,
|
|
GsubSetup,
|
|
HavingFieldsSetup,
|
|
HeadSetup,
|
|
HistogramSetup,
|
|
JSONParseSetup,
|
|
JSONStringifySetup,
|
|
JoinSetup,
|
|
LabelSetup,
|
|
Latin1ToUTF8Setup,
|
|
LeastFrequentSetup,
|
|
MergeFieldsSetup,
|
|
MostFrequentSetup,
|
|
NestSetup,
|
|
NothingSetup,
|
|
PutSetup,
|
|
RankSetup,
|
|
RegularizeSetup,
|
|
RemoveEmptyColumnsSetup,
|
|
RenameSetup,
|
|
ReorderSetup,
|
|
RepeatSetup,
|
|
ReshapeSetup,
|
|
SampleSetup,
|
|
Sec2GMTDateSetup,
|
|
Sec2GMTSetup,
|
|
SeqgenSetup,
|
|
ShuffleSetup,
|
|
SkipTrivialRecordsSetup,
|
|
SortSetup,
|
|
SortWithinRecordsSetup,
|
|
SparklineSetup,
|
|
SparsifySetup,
|
|
SplitSetup,
|
|
SsubSetup,
|
|
Stats1Setup,
|
|
Stats2Setup,
|
|
StepSetup,
|
|
SubSetup,
|
|
SummarySetup,
|
|
SurvSetup,
|
|
TacSetup,
|
|
TailSetup,
|
|
TeeSetup,
|
|
TemplateSetup,
|
|
TopSetup,
|
|
UTF8ToLatin1Setup,
|
|
UnflattenSetup,
|
|
UniqSetup,
|
|
UnspaceSetup,
|
|
UnsparsifySetup,
|
|
}
|
|
|
|
func ShowHelpForTransformer(verb string) bool {
|
|
transformerSetup := LookUp(verb)
|
|
if transformerSetup != nil {
|
|
fmt.Println(colorizer.MaybeColorizeHelp(transformerSetup.Verb, true))
|
|
transformerSetup.UsageFunc(os.Stdout)
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func ShowHelpForTransformerApproximate(searchString string) bool {
|
|
found := false
|
|
for _, transformerSetup := range TRANSFORMER_LOOKUP_TABLE {
|
|
if strings.Contains(transformerSetup.Verb, searchString) {
|
|
fmt.Println(colorizer.MaybeColorizeHelp(transformerSetup.Verb, true))
|
|
transformerSetup.UsageFunc(os.Stdout)
|
|
found = true
|
|
}
|
|
}
|
|
return found
|
|
}
|
|
|
|
func LookUp(verb string) *TransformerSetup {
|
|
for _, transformerSetup := range TRANSFORMER_LOOKUP_TABLE {
|
|
if transformerSetup.Verb == verb {
|
|
return &transformerSetup
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetVerbNames returns all verb names, in table order, for use as
|
|
// shell-completion candidates (pkg/terminals/completion).
|
|
func GetVerbNames() []string {
|
|
verbNames := make([]string, len(TRANSFORMER_LOOKUP_TABLE))
|
|
for i, transformerSetup := range TRANSFORMER_LOOKUP_TABLE {
|
|
verbNames[i] = transformerSetup.Verb
|
|
}
|
|
return verbNames
|
|
}
|
|
|
|
func ListVerbNamesVertically() {
|
|
for _, transformerSetup := range TRANSFORMER_LOOKUP_TABLE {
|
|
fmt.Printf("%s\n", transformerSetup.Verb)
|
|
}
|
|
}
|
|
|
|
func ListVerbNamesAsParagraph() {
|
|
verbNames := make([]string, len(TRANSFORMER_LOOKUP_TABLE))
|
|
|
|
for i, transformerSetup := range TRANSFORMER_LOOKUP_TABLE {
|
|
verbNames[i] = transformerSetup.Verb
|
|
}
|
|
|
|
lib.PrintWordsAsParagraph(verbNames)
|
|
}
|
|
|
|
func UsageVerbs() {
|
|
separator := "================================================================"
|
|
|
|
for i, transformerSetup := range TRANSFORMER_LOOKUP_TABLE {
|
|
if i > 0 {
|
|
fmt.Println()
|
|
}
|
|
fmt.Printf("%s\n", separator)
|
|
lib.InternalCodingErrorIf(transformerSetup.UsageFunc == nil)
|
|
fmt.Println(colorizer.MaybeColorizeHelp(transformerSetup.Verb, true))
|
|
transformerSetup.UsageFunc(os.Stdout)
|
|
}
|
|
fmt.Printf("%s\n", separator)
|
|
}
|