2016-05-11 1 views
1

私は各カラムが一意のサンプルを表し、各行が遺伝子名に対応する多くのデータファイルを持っています。ここに私の小さなファイルの一つのサンプルです:最初の列にAWK:重複したエントリの異なる値を平均で置き換えます。

MAPK3 9.49707613464767 9.34083460789419 9.12918870414545 
TIE1 5.12900020712651 5.15008091018047 5.15008091018047 
CYP2C19 3.80757247946463 3.80757247946463 3.87721584865861 
CXCR5 6.40745840005515 6.40745840005515 6.40745840005515 
CXCR5 6.04763929379884 6.13038198258514 6.13038198258514 
DUSP1 12.0320377077951 12.7960658385305 12.625340661444 
MMP10 4.1933379022831 4.1933379022831 4.1933379022831 
RXRG 4.33755505408386 4.32903686336417 4.32903686336417 
RXRG 6.91141485189572 6.96893082690402 6.96893082690402 

お知らせ、遺伝子名CXCR5RXRGが複製されているが、各エントリの値が異なっています。

MAPK3 9.49707613464767 9.34083460789419 9.12918870414545 
TIE1 5.12900020712651 5.15008091018047 5.15008091018047 
CYP2C19 3.80757247946463 3.80757247946463 3.87721584865861 
CXCR5 6.22754884693 6.2689201913201 6.2689201913201 
DUSP1 12.0320377077951 12.7960658385305 12.625340661444 
MMP10 4.1933379022831 4.1933379022831 4.1933379022831 
RXRG 5.6244849529898 5.6489838451341 5.6489838451341 
重複遺伝子の値が平均化され

サンプルあたり、元のエントリを置き換える:私は必要な出力ファイルは次のようになります。さらに、ユニークな遺伝子名と値をそのまま残しておきたい。明らかにするために、カラム1では重複する遺伝子名ごとに、列ごとではなく行全体で平均値を求めたくありません。 ここでは、calculate and print the average value of strings in a columnのように巧妙なawk one-linersを利用しようとしましたが、 Average from different columns in shell script。しかし、私は100のサンプル/列を持つことができる私のファイルを説明するコマンドを一般化するのに問題があります。そして彼らは私のユニークな遺伝子名を不必要に混乱させます。

私の初心者レベルのコーディングスキルが私の死になります!助言がありますか?救助へ

おかげ

答えて

1
$ cat tst.awk 
NR == 1 { CONVFMT="%."length($2)-index($2,".")"f" } 
$1 != key { prt() } 
{ 
    key=$1 
    for (i=2 ; i<=NF ; i++) { 
     sum[i] += $i 
    } 
    cnt++ 
} 
END { prt() } 

function prt() { 
    if (key != "") { 
     printf "%s", key 
     for (i=2; i<=NF; i++) { 
      printf "%s%s", OFS, sum[i]/cnt 
     } 
     print "" 
    } 
    delete sum 
    cnt = 0 
} 

$ awk -f tst.awk file 
MAPK3 9.49707613464767 9.34083460789419 9.12918870414545 
TIE1 5.12900020712651 5.15008091018047 5.15008091018047 
CYP2C19 3.80757247946463 3.80757247946463 3.87721584865861 
CXCR5 6.22754884692699 6.26892019132015 6.26892019132015 
DUSP1 12.03203770779510 12.79606583853050 12.62534066144400 
MMP10 4.19333790228310 4.19333790228310 4.19333790228310 
RXRG 5.62448495298979 5.64898384513410 5.64898384513410 
+1

これは私が探していたものです。コードについて説明してください。 –

+1

最初の行は、ファイル内の最初の値に基づいて使用している精度を計算します。この値は、他のすべての計算に使用されます。 2行目は、前のキーに関連付けられた値を出力するためにキー値が変更されたときにprt()を呼び出します。次のブロック(現在のキーが前のキーと同じであるたびに実行される)は、各フィールドの値を合計し、そのキーを持つ行の数が読み取られた回数を保持します。 ENDセクションは、読み込まれた最後のキーの値を出力するためにprt()を呼び出します。 prt()関数は値を出力します。 –

1

awk!デコレート/ソート/デコレートパターンを使用して、行の順序を同じに保ちます。

$ awk '{f2[$1]+=$2; f3[$1]+=$3; f4[$1]+=$4; c[$1]++; r[$1]=NR} 
    END{for(k in c) print r[k] "\t" k, f2[k]/c[k], f3[k]/c[k], f4[k]/c[k]}' file | 
sort -n | cut -f2 

MAPK3 9.49708 9.34083 9.12919 
TIE1 5.129 5.15008 5.15008 
CYP2C19 3.80757 3.80757 3.87722 
CXCR5 6.22755 6.26892 6.26892 
DUSP1 12.032 12.7961 12.6253 
MMP10 4.19334 4.19334 4.19334 
RXRG 5.62448 5.64898 5.64898 

小数点以下の桁数を指定すると、修飾子付きのprintfに切り替えることができます。

1

私はawkに非常に新しいですが、これはトリックを行うことが(私のために働くように見える)

#!/bin/awk -f 

{ 
    for(i = 2; i <= 4; ++i) 
     id[$1][i] = (id[$1][i] * num[$1] + $i)/(num[$1] + 1); 
    ++num[$1] 
} 

END { 
    for(key in num) 
     printf "%s %.15g %.15g %.15g \n", key, id[key][2], id[key][3], id[key][4] 
} 

出力:

$ cat test.txt|test.awk 
MMP10 4.1933379022831 4.1933379022831 4.1933379022831 
DUSP1 12.0320377077951 12.7960658385305 12.625340661444 
CYP2C19 3.80757247946463 3.80757247946463 3.87721584865861 
TIE1 5.12900020712651 5.15008091018047 5.15008091018047 
CXCR5 6.22754884692699 6.26892019132015 6.26892019132015 
RXRG 5.62448495298979 5.6489838451341 5.6489838451341 
MAPK3 9.49707613464767 9.34083460789419 9.12918870414545 

これは、上キー連想配列を作ります最初の列の名前と実行中の平均を保持します。

関連する問題