ファイルから各オブジェクトの最大値を抽出する [重複]

ファイルから各オブジェクトの最大値を抽出する [重複]

bashCentOSシステムのファイルからいくつかの値を抽出する必要があります。myfile.txtというオブジェクトのリストがあります。Info_region各オブジェクトはコード(たとえば、など)で識別されBARD1_region_005ますBIRC2_region_002。また、いくつかの数値変数を報告する他の列もあります。私のファイルで同じオブジェクト(同じコード名)を複数回繰り返すことができます。また、重複していないすべてのターゲットコードの完全なリストを含むファイルもあります。 list-file.txtに示されているように、各オブジェクト(コード名)が一度だけ報告されるoutput.txtファイルを取得したいので、myfileの対応するコード名に関連付けられている可能な最大値をこのファイルに関連付けたいとします。 TXT。

myfile.txt:(列は区切りtab

Info_region Lig_score   Lig_prevista    Lig_prevista_+1 Int_score   Expo_score  Protac_score
BARD1_region_005    0   3   3   0   1   1
BARD1_region_006    0   1   1   0   1   1
BIRC2_region_001    1   6   7   0   1   2
BIRC2_region_001    1   7   8   0   1   2
BIRC2_region_001    0   2   2   0   0   0
BIRC2_region_001    0   12  12  0   1   1
BIRC2_region_001    1   10  11  -1  1   1
BIRC2_region_001    1   2   3   0   1   2
BIRC2_region_001    1   0   1   0   1   2
BIRC2_region_001    1   6   7   0   1   2
BIRC2_region_002    0   0   0   0   1   1
BIRC2_region_002    1   0   0   -1  0.5 0.5
BIRC2_region_003    0   0   0   0   1   1
BIRC2_region_004    0   1   1   0   1   1
UHRF1_region_004    0   0   0   1   1   2
UHRF1_region_004    0   0   0   1   1   2
UHRF1_region_004    1   0   1   0   0.5 1.5
UHRF1_region_004    0   0   0   1   1   2
UHRF1_region_005    0   3   3   1   1   2
UHRF1_region_005    1   0   0   -1  1   1

ファイルのリスト.txt:

Info_region
BARD1_region_005
BARD1_region_006
BIRC2_region_001
BIRC2_region_002
BIRC2_region_003
BIRC2_region_004
UHRF1_region_004
UHRF1_region_005

出力.txt:

Info_region Lig_score   Lig_prevista    Lig_prevista_+1 Int_score   Expo_score  Protac_score
BARD1_region_005    0   3   3   0   1   1
BARD1_region_006    0   1   1   0   1   1
BIRC2_region_001    1   12  12  0   1   2
BIRC2_region_002    1   0   0   0   1   1
BIRC2_region_003    0   0   0   0   1   1
BIRC2_region_004    0   1   1   0   1   1
UHRF1_region_004    1   0   1   1   1   2
UHRF1_region_005    1   3   3   1   1   2

誰でも私を助けることができますか?ありがとうございます!

答え1

データが呼び出されたファイルにあり、最初の列にソートされていると仮定fileすると、GNUdatamashユーティリティはデータファイルで一度にこれを実行できます。

datamash -H -W -g 1 max 2-7 <file

これは、ユーティリティが空白で区切られた列(-W;列が実際にタブで区切られている場合はこの列を削除)を使用し、ヘッダー付きのデータの最初の行()を持ち、最初の列-H()でグループ化-g 1し、最大値を計算するように指示します。 2列から7列までです。

質問のデータを考慮すると、結果は次のようになります。

GroupBy(Info_region)    max(Lig_score)  max(Lig_prevista)       max(Lig_prevista_+1)    max(Int_score)     max(Expo_score) max(Protac_score)
BARD1_region_005        0       3       3       0       1       1
BARD1_region_006        0       1       1       0       1       1
BIRC2_region_001        1       12      12      0       1       2
BIRC2_region_002        1       0       0       0       1       1
BIRC2_region_003        0       0       0       0       1       1
BIRC2_region_004        0       1       1       0       1       1
UHRF1_region_004        1       0       1       1       1       2
UHRF1_region_005        1       3       3       1       1       2

--header-ininを使用して-Hヘッダーレス出力を取得し、生データファイルからヘッダーを取得することもできます。

{ head -n 1 file; datamash --header-in -W -g 1 max 2-7 <file; } >output

ここでは結果をoutput


タブで区切られたフィールドを使用awkするとします。

awk -F '\t' '
    BEGIN { OFS = FS }
    NR == 1 { print; next }
    {
        n[$1] = 1
        for (i = 2; i <= NF; ++i)
            a[$1,i] = (a[$1,i] == "" || $i > a[$1,i] ? $i : a[$1,i])
    }
    END { 
        nf = NF
        for (j in n) {
            $0 = j
            for (i = 2; i <= nf; ++i)
                $i = a[$1,i]
            print
         }
     }' file

これにより、各グループの各列の最大値が計算されます。数値は、グループ名のみをキーとして保持する配列aに格納されます。n

答え2

私はあなたが実際にbashでこれをしたくはありませんが(そうではありませんが)、他のツールを使用することに興味があるとします。 GNUawkメソッドは次のとおりです。

$ gawk -vOFS="\t" -F'\t' \
    '{ 
        if(NR==1){print; } 
        else{ 
            for(i=2;i<=NF;i++){ 
                if($i > a[$1][i] || ! a[$1][i]){a[$1][i]=$i}
           }
        } 
     }
     END{ 
        for (region in a){ 
            printf "%s", region; 
            for(i=2;i<=NF;i++){ 
                printf "%s%s", OFS,a[region][i]
            } 
            printf "\n";  
        } 
     }' myfile.txt 
Info_region Lig_score   Lig_prevista    Lig_prevista_+1 Int_score   Expo_score  Protac_score
BIRC2_region_001    1   12  12  0   1   2
BIRC2_region_002    1   0   0   -1  1   1
BIRC2_region_003    0   0   0   0   1   1
BIRC2_region_004    0   1   1   0   1   1
BARD1_region_005    0   3   3   0   1   1
BARD1_region_006    0   1   1   0   1   1
UHRF1_region_004    1   0   1   1   1   2
UHRF1_region_005    1   3   3   1   1   2

答え3

これは、実際の多次元配列やシミュレートされた多次元を使用しないアプローチです。代わりに、同じキーにチャンクを保存します。

awk '
BEGIN { OFS = FS = "\t" }
NR==1 { print; next }
{
  obj = $1; $1=""; sub(FS, "")
  a[obj] = a[obj] $0 FS
}
END {
  nf0 = NF
  for (obj in a) {
    $1 = obj
    nf = split(a[obj], f)
    for (i=1; i<=nf0; i++) {
      $(i+1) = f[i]
      for (j=0; j<int(nf/nf0); j++) {
        idx = i + nf0*j
        if ( f[idx] > $(i+1) ) $(i+1) = f[idx]
      }
    }
    print
  }
}
' myfile.txt

関連情報