2016-12-16 10 views
1

多くの列からグループ化したり数えたりするのに助けが必要です。3つの列でグループ化してテーブルを作成する(最高のawk)

INPUT:tsvファイル。

1,2,4列でソートされています。

ヘッダ:文字列は、値、長さ、停止、開始

chr1 56971 57065 94  0.287234 
chr1 565460 565601 141  0.411348 
chr1 754342 754488 146  0.520548 
chr1 783856 784002 146  0.315068 
chr1 789652 789768 116  0.310345 
chr1 790532 790628 96  0.520833 
chr2 1744623 1744774 151  0.509934 
chr2 1744623 1744774 151  0.509934 
chr2 1744623 1744774 151  0.509934 
chr2 1748501 1748635 134  0.440299 
chr2 1748501 1748636 135  0.444444 

OUTPUT:

    0-10 length ... 90-100 ............140-150... 190-200 
chr1:0-60000   A1(0), B1(0)..A2(1),B2(0.287234).. A,B ... An,Bn 
chr1:60000-120000   .    .     .   . 
.       .    .     .   . 
.       .    .     .   . 
chr1:780000-840000  0,0  ..... 1,0.520833 ......1,0.315068..A,B 
chr2:0-60000   A1,B1 ..... .  ...... .  .. . 

A =(入力から3列まで2Nのための)間隔0から60000までの行数

B =(行の数値)で割った入力に5列の合計

第一グループの第1 COによる

for i in {0..249480000..60000} 

によって、長さごとにグループ化された行のこの領域のカウント数(0..200..10)

ためlumnと作成領域は、私が試した:今

for z in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 X Y 
do 
for i in {0..249480000..60000} 
    do 
u=$i 
let "u +=60000" 

「とI次のことを知らない "。

私は1つの列でグループ化を知っている:

awk -F, 'NR>1{arr[$1]++}END{for (a in arr) print a, arr[a]}' 

が、これは私にとって本当に難しいです。私を助けてくれますか?素子の大きさに基づいて

模造多次元な配列(1つの指数が、3 要素で構成)を使用して
+0

与えられた入力に必要な正確な出力を表示するように[編集]してください。このようにすれば、より明確になります。 – fedorqui

+0

それは良いですか?申し訳ございません.. – Vonton

+0

区間の境界を越える範囲はどうなりますか? – Thor

答えて

1
awk -v Separator=' | ' ' 
    BEGIN{ LenStepSize = 10 ; IntStepSize = 60000 } 
    { 
    # Store the labels 
    Labels[ $1]++ 

    # Adapt the Step array size 
    if (IntLastIndex * IntStepSize < $3) IntLastIndex = int($3/IntStepSize) + 1 
    IntIdx = int($3/IntStepSize) 

    # Adapt the Length array size 
    if(LenLastIndex * LenStepSize < $4) LenLastIndex = int($4/LenStepSize) + 1 
    LenIdx = int($4/LenStepSize) 

    # Create the mono "multi" index reference 
    Idx = $1 "-" IntIdx "-" LenIdx 

    # store the data element 
    As[ Idx]++ 
    Bs[ Idx] += $5 
    #printf("DEBUG: As[%s]: %s | Bs[%s]:%s (+%s)\n", Idx, As[ Idx], Idx, Bs[ Idx], $5) 
    } 

    END { 
     # Print the header 
     printf("Object    ") 
     for (Leng = 0; Leng <= LenLastIndex; Leng++) printf("%s%3d - %3d", Separator, Leng, (Leng + 1) * LenStepSize) 
     printf("\n      ") 
     for (Leng = 0; Leng <= LenLastIndex; Leng++) printf("%s length ", Separator) 

     # print each element (empty or with value) 
     # - lines per label 
     for (Label in Labels) { 
      # - per sub section of intervale 
      for (Inter = 0; Inter <= IntLastIndex; Inter++) { 
      printf("\n%5s %7d-%7d", Label, Inter * IntStepSize, (Inter + 1) * IntStepSize - 1) 

      # column per length section 
      for (Leng = 0; Leng <= LenLastIndex; Leng++) { 
       Idx = Label "-" Inter "-" Leng 
       printf("%s%d , " (Bs[ Idx] > 0 ? "%2.3f" : "%-5d") , Separator, As[ Idx], Bs[ Idx]/(As[ Idx] > 0 ? As[ Idx] : 1)) 
       } 
      } 
      print "" 
      } 
     } 
    ' tsv.file 
  • ダイナミック(メモリ内の巨大ほぼ空の配列を作成するために避ける)
  • はありません
  • 出力形式(これはメモリ衝撃に)巨大なデータファイルのスイートが塩基性である(コンテンツに基づいた列または行サイズ、...)
    • はあなたの本当のニーズに合った(、...「」宇宙のようにか)のカラム(この場合は)見ていますが、セパレータとして任意のパターンを設定できるようにするのawkの開始時にSeparator変数を追加
+0

私はそれを試しましたが、行数はうまくいくが、値Bはうまくいかない:-(しかし、それは本当に素晴らしい仕事で、私は驚いている。 – Vonton

+0

あなたのスクリプトのどこに問題があるかもしれないが、私はしませんでした:-(まだ時間が私は値をカウント( "B")に問題があります:-(私はそれが整数だけを表示しているが、浮動小数点(fe:0.45)が必要と思う – Vonton

+0

は、 Bの '%d'は10進数ではないので、 '%2.3f'で変更し、その他の書式設定出力を – NeronLeVelu

関連する問題