파일에서 각 개체의 최대값 추출 [중복]

파일에서 각 개체의 최대값 추출 [중복]

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첫 번째 열에 정렬되어 있다고 가정하면 GNU datamash유틸리티는 데이터 파일에서만 한 번에 이 작업을 수행할 수 있습니다.

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에서 이 작업을 수행하고 싶지 않지만(그러면 안 되지만) 다른 도구를 사용할 의향이 있다고 가정합니다. GNU awk방법은 다음과 같습니다.

$ 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

관련 정보