Milllerでunnestする

Millerは「CSV、TSV、JSONのためのjq」みたいなツールです。

ちょうど報告してたissueが一瞬で直ったので、nestの使い方メモ。

github.com

nest

ドキュメント:http://johnkerl.org/miller/doc/reference-verbs.html#nest

こういう感じのことができます。Rで言うとtidyr::separate()とかtidyr::unnest()みたいな。

$ echo '[{"x":1,"y":"a"},{"x":2,"y":"d,e,f"},{"x":3,"y":"g,h"}]' | \
>      mlr --ijson nest --explode --values --across-records --nested-fs ',' -f y
x=1,y=a
x=2,y=d
x=2,y=e
x=2,y=f
x=3,y=g
x=3,y=h

これ見てわかるように、指定しないといけないオプションが多い。。それぞれ見ていきましょう。

-f

これは展開するフィールドを指定します。

--nested-fs,--nested-ps

--nested-fsはfield separator、つまり各フィールドの間にくる文字列です。--nested-psはpair separator、つまりフィールド名と値の間にくる文字列です。たとえば、

nested_field=a:1;b:2

みたいなのがあったとすると、--nested-fs;--nested-ps:です。ちなみにこれはそれぞれ;:がデフォルトの文字なので、この場合は省略できます。

--explode/--implode

どちらかを指定する必要があります。これは、ネストしたフィールドを展開するか、逆に複数のフィールドをネストさせるか、というオプションです。まあ--explodeを使うことの方が多いでしょう。

--values/--pairs

どちらかを指定する必要があります。--valuesは値の連続になってるやつに使います。--pairsはキーと値のペアになっているやつに使います。

$ echo -e 'x=1;2;3\nx=4;5' | \
>      mlr nest --explode --values --across-records -f x
x=1
x=2
x=3
x=4
x=5
$ echo -e 'x=a:1;b:2,y=apple\nx=a:4;b:5,y=banana' | \
>      mlr nest --explode --pairs --across-records -f x
a=1,y=apple
b=2,y=apple
a=4,y=banana
b=5,y=banana

--across-records/--across-fields

これは、ネストしたフィールドを行方向に展開するか、列方向に展開するかを選びます。さっきの同じのを--across-fieldsに変えると、こんな感じになります。

$ echo -e 'x=1;2;3\nx=4;5' | \
>      mlr nest --explode --values --across-fields -f x
x_1=1,x_2=2,x_3=3
x_1=4,x_2=5
$ echo -e 'x=a:1;b:2,y=apple\nx=a:4;b:5,y=banana' | \
>      mlr nest --explode --pairs --across-fields -f x
a=1,b=2,y=apple
a=4,b=5,y=banana

感想

むずい。これに関しては、やっぱRでよくない?ってなった。