diff --git a/c/cli/mlrcli.c b/c/cli/mlrcli.c index 285211bba..51c741b5b 100644 --- a/c/cli/mlrcli.c +++ b/c/cli/mlrcli.c @@ -1334,7 +1334,7 @@ int cli_handle_reader_options(char** argv, int argc, int *pargi, cli_reader_opts preader_opts->allow_repeat_ifs = TRUE; argi += 1; - } else if (streq(argv[argi], "--json-skip-arrays-on-input")) { // xxx to mlr -h + } else if (streq(argv[argi], "--json-skip-arrays-on-input")) { preader_opts->json_skip_arrays_on_input = TRUE; argi += 1; diff --git a/c/todo.txt b/c/todo.txt index c3f3f6a79..f4c1ee9b8 100644 --- a/c/todo.txt +++ b/c/todo.txt @@ -10,7 +10,6 @@ BUGFIXES - incl. json-skip-arrays-on-input * feature-counting script to cookbook -* json_encode / json_decode functions? (map->string and string->map) ? mlrfunc docsection? ! windows port @@ -170,6 +169,8 @@ COMPARES: ================================================================ 5.2.0 IDEAS: +* json_encode / json_decode functions? (map->string and string->map) + * strptime/strftime: - strptime w/ fractional seconds. maybe %OS? - strftime: %OS1-%OS9? diff --git a/doc/content-for-cookbook.html b/doc/content-for-cookbook.html index e508f2792..a1ba164ea 100644 --- a/doc/content-for-cookbook.html +++ b/doc/content-for-cookbook.html @@ -287,6 +287,27 @@ or, more simply, POKI_INCLUDE_AND_RUN_ESCAPED(data/ragged-csv-2.sh)HERE + + +

Feature-counting

+ +
+ +

Suppose you have some heterogeneous data like this: + +POKI_INCLUDE_ESCAPED(data/features.json)HERE + +

A reasonable question to ask is, how many occurrences of each field are +there? And, what percentage of total row count has each of them? Since the +denominator of the percentage is not known until the end, this is a two-pass +algorithm: + +POKI_INCLUDE_ESCAPED(data/feature-count.mlr)HERE + +

Then +POKI_RUN_COMMAND{{mlr --json put -q -f data/feature-count.mlr data/features.json}}HERE +POKI_RUN_COMMAND{{mlr --ijson --opprint put -q -f data/feature-count.mlr data/features.json}}HERE +

Unsparsing

diff --git a/doc/cookbook.html b/doc/cookbook.html index 644722013..a6e4acb2c 100644 --- a/doc/cookbook.html +++ b/doc/cookbook.html @@ -205,6 +205,7 @@ Miller commands were run with pretty-print-tabular output format.     • Two-pass algorithms: records having max value
• Rectangularizing data
• Regularizing ragged CSV
+• Feature-counting
• Unsparsing
• Parsing log-file output
• Memoization with out-of-stream variables
@@ -1150,6 +1151,101 @@ a,b,c

+ + +

Feature-counting

+ +
+ +

Suppose you have some heterogeneous data like this: + +

+

+
+{ "qoh": 29874, "rate": 1.68, "latency": 0.02 }
+{ "name": "alice", "uid": 572 }
+{ "qoh": 1227, "rate": 1.01, "latency": 0.07 }
+{ "qoh": 13458, "rate": 1.72, "latency": 0.04 }
+{ "qoh": 56782, "rate": 1.64, "latency": 0.02 }
+{ "qoh": 23512, "rate": 1.71, "latency": 0.03 }
+{ "qoh": 9876, "rate": 1.89, "latency": 0.08 }
+{ "name": "bill", "uid": 684 }
+{ "name": "chuck", "uid": 908 }
+{ "name": "dottie", "uid": 440 }
+{ "qoh": 0, "rate": 0.40, "latency": 0.01 }
+{ "qoh": 5438, "rate": 1.56, "latency": 0.17 }
+
+
+

+ +

A reasonable question to ask is, how many occurrences of each field are +there? And, what percentage of total row count has each of them? Since the +denominator of the percentage is not known until the end, this is a two-pass +algorithm: + +

+

+
+for (key in $*) {
+  @key_counts[key] += 1;
+}
+@record_count += 1;
+
+end {
+  for (key in @key_counts) {
+      @key_fraction[key] = @key_counts[key] / @record_count
+  }
+  emit @record_count;
+  emit @key_counts, "key";
+  emit @key_fraction,"key"
+}
+
+
+

+ +

Then +

+

+
+$ mlr --json put -q -f data/feature-count.mlr data/features.json
+{ "record_count": 12 }
+{ "key": "qoh", "key_counts": 8 }
+{ "key": "rate", "key_counts": 8 }
+{ "key": "latency", "key_counts": 8 }
+{ "key": "name", "key_counts": 4 }
+{ "key": "uid", "key_counts": 4 }
+{ "key": "qoh", "key_fraction": 0.666667 }
+{ "key": "rate", "key_fraction": 0.666667 }
+{ "key": "latency", "key_fraction": 0.666667 }
+{ "key": "name", "key_fraction": 0.333333 }
+{ "key": "uid", "key_fraction": 0.333333 }
+
+
+

+

+

+
+$ mlr --ijson --opprint put -q -f data/feature-count.mlr data/features.json
+record_count
+12
+
+key     key_counts
+qoh     8
+rate    8
+latency 8
+name    4
+uid     4
+
+key     key_fraction
+qoh     0.666667
+rate    0.666667
+latency 0.666667
+name    0.333333
+uid     0.333333
+
+
+

+

Unsparsing

diff --git a/doc/data/feature-count.mlr b/doc/data/feature-count.mlr new file mode 100644 index 000000000..4a4a97691 --- /dev/null +++ b/doc/data/feature-count.mlr @@ -0,0 +1,13 @@ +for (key in $*) { + @key_counts[key] += 1; +} +@record_count += 1; + +end { + for (key in @key_counts) { + @key_fraction[key] = @key_counts[key] / @record_count + } + emit @record_count; + emit @key_counts, "key"; + emit @key_fraction,"key" +} diff --git a/doc/data/features.json b/doc/data/features.json new file mode 100644 index 000000000..cc212ffe7 --- /dev/null +++ b/doc/data/features.json @@ -0,0 +1,12 @@ +{ "qoh": 29874, "rate": 1.68, "latency": 0.02 } +{ "name": "alice", "uid": 572 } +{ "qoh": 1227, "rate": 1.01, "latency": 0.07 } +{ "qoh": 13458, "rate": 1.72, "latency": 0.04 } +{ "qoh": 56782, "rate": 1.64, "latency": 0.02 } +{ "qoh": 23512, "rate": 1.71, "latency": 0.03 } +{ "qoh": 9876, "rate": 1.89, "latency": 0.08 } +{ "name": "bill", "uid": 684 } +{ "name": "chuck", "uid": 908 } +{ "name": "dottie", "uid": 440 } +{ "qoh": 0, "rate": 0.40, "latency": 0.01 } +{ "qoh": 5438, "rate": 1.56, "latency": 0.17 }