bash
CentOSシステムのファイルからいくつかの値を抽出する必要があります。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-in
inを使用して-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