2017-02-27 5 views
1

私が持っているデータ:TXR:連結テーブルをピボットする方法このようになります

i,key,val 
1,a,0.2 
1,b,3.2 
1,c,4.5 
2,a,0.8 
2,b,4.1 
2,c,3.5 
3,a,0.5 
3,b,3.1 
3,c,4.1 
4,a,3.2 
4,b,5.2 
4,c,7.1 
4,d,1.1 
5,a,2.8 
5,b,5.1 
5,c,8.5 
5,d,0.9 
6,a,2.5 
6,b,5.1 
6,c,8.1 
6,d,1.0 
7,a,3.2 
7,b,5.2 
8,a,2.8 
8,b,5.1 
9,a,2.5 
9,b,5.1 

私の現在の間違ったTXRスクリプトは次のとおりです:

@(output) 
i,key,val 
@(end) 
@(repeat) 
i,@(coll)@{key /[^,]+/}@(end) 
@ (collect :gap 0) 
@{i /[0-9]+/},@(coll)@{value /[^,]+/}@(end) 
@ (end) 
@ (output) 
@ (repeat) 
@  (repeat) 
@i,@key,@value 
@  (end) 
@ (end) 
@ (end) 
@(end) 
私はこのように見えるようにTXRでそれを処理したい

i,a,b,c 
1,0.2,3.2,4.5 
2,0.8,4.1,3.5 
3,0.5,3.1,4.1 
i,a,b,c,d 
4,3.2,5.2,7.5,1.1 
5,2.8,5.1,8.5,0.9 
6,2.5,5.1,8.1,1.0 
i,a,d 
7,3.2,5.2 
8,2.8,5.1 
9,2.5,5.1 

代わりに、次のものが生成されます。

i,key,val 
1,a,0.2 
1,a,3.2 
1,a,4.5 
2,b,0.8 
2,b,4.1 
2,b,3.5 
3,c,0.5 
3,c,3.1 
3,c,4.1 
4,a,3.2 
4,a,5.2 
4,a,7.5 
4,a,1.1 
5,b,2.8 
5,b,5.1 
5,b,8.5 
5,b,0.9 
6,c,2.5 
6,c,5.1 
6,c,8.1 
6,c,1.0 
7,a,3.2 
7,a,5.2 
8,d,2.8 
8,d,5.1 
9,,2.5 
9,,5.1 

希望の出力を得るにはどうすればよいですか?何とか@(merge)を使うことができますか?それとも、lispに落とす必要がありますか?私は、これに便利なtranspose関数があることを知りました。

答えて

1

コードはほぼあります。問題は、値がキーに関連付けられていなければならないことです。これを行うために、我々は2016年6月29日にリリースさTXR 144に追加された機能の利点を活かすことができます:collectcollでサポート:counterキーワード:

@(output) 
i,key,val 
@(end) 
@(repeat) 
i,@(coll)@{keylist /[^,]+/}@(end) 
@ (collect :gap 0) 
@{i /[0-9]+/},@(coll :counter c)@{value /[^,]+/}@(bind key @[keylist c])@(end) 
@ (end) 
@ (output) 
@ (repeat) 
@  (repeat) 
@i,@key,@value 
@  (end) 
@ (end) 
@ (end) 
@(end) 

をキーが代わりにkeylist変数に収集されていますkeyであり、keyvalueと結合し、keylistにインデックス付けすると、cとなる。カウンタcは、デフォルトで0からステップしています。 :counter (c expr)で異なる開始値を指定することができます。

しかし、このようにしてやってみましょう。私たちは何をしているのかを見てみましょう:このカウンタをkeysを繰り返し繰り返し、値の並びにキーのリストをちょうど収集しています。

@(output) 
i,key,val 
@(end) 
@(repeat) 
i,@(coll)@{keylist /[^,]+/}@(end) 
@ (collect :gap 0) 
@{i /[0-9]+/},@(coll)@{value /[^,]+/}@(end) 
@ (bind key keylist) 
@ (end) 
@ (output) 
@ (repeat) 
@  (repeat) 
@i,@key,@value 
@  (end) 
@ (end) 
@ (end) 
@(end) 

を参照してください:私たちは、このようなインナーcollの単一bind外、と正確に同じことを達成することができますか?各行にvalueリストを取得するために、値を収集します。キーは行ごとに変わらないので、keyリストをvalueとペアにするには、keylistからバインドするだけです。

私たちがこのロジックでやりたいことは、印刷された出力を得ることだけであれば、行を収集して各行の後に出力することはできません。言い換えれば、それはキー名を収集中だけの運動だし、その後、与えられたセクションの各列の値と一緒にそれらをダンプ:

おそらく
@(output) 
i,key,val 
@(end) 
@(repeat) 
i,@(coll)@{key /[^,]+/}@(end) 
@ (repeat :gap 0) 
@{i /[0-9]+/},@(coll)@{value /[^,]+/}@(end) 
@ (output) 
@  (repeat) 
@i,@key,@value 
@  (end) 
@ (end) 
@ (end) 
@(end) 

、これはAwkのために良い仕事です。必ずしもUnixのものではありません。あなたを気にしてください:

(awk (:set fs "," ofs ",") 
    (:let keys) 
    (:begin (prn 'i 'key 'val)) 
    ((equal [f 0] "i") (set keys (rest f)) 
         (next)) 
    (f (each ((k keys) 
       (v (rest f))) 
      (prn [f 0] k v)))) 
+0

ありがとう、もう一度!簡単にTXRがこの問題をどのように処理したかに非常に感銘を受けました。 – wdkrnls

関連する問題