큰 테이블 파일을 awk와 병합하는 방법은 무엇입니까?

큰 테이블 파일을 awk와 병합하는 방법은 무엇입니까?

열에 21개의 테이블 필드가 있는 파일이 있습니다. 탭 14와 15는 탭 10의 변수에 대해 여러 번(최대 ":") 반복되는 데이터 세트이고, 탭 11에는 탭 10에 대한 수치 설명 데이터가 있습니다.

다음은 입력의 예입니다.

399 3   0   0   0   0   0   0   -   chromosome_1_Contig0.1980:10701-11103   402 0   402 gi|952977790|ref|NM_001317128.1|    849 447 849 1   402 0   447
281 0   0   0   0   0   0   0   -   chromosome_1_Contig0.1980:11209-11490   281 0   281 gi|952977790|ref|NM_001317128.1|    849 166 447 1   281 0   166
166 0   0   0   0   0   0   0   -   chromosome_1_Contig0.1980:11588-11754   166 0   166 gi|952977790|ref|NM_001317128.1|    849 0   166 1   166 0   0
51  0   0   0   0   0   0   0   +   chromosome_1_Contig0.3916:1547-1598 51  0   51  gi|733214878|ref|NM_001303082.1|    708 0   51  1   51  0   0
132 0   0   0   0   0   0   0   +   chromosome_1_Contig0.3916:3201-3333 132 0   132 gi|733214878|ref|NM_001303082.1|    708 282 414 1   132 0   282
294 0   0   0   0   0   0   0   +   chromosome_1_Contig0.3916:3412-3706 294 0   294 gi|733214878|ref|NM_001303082.1|    708 414 708 1   294 0   414
103 4   0   0   0   0   0   0   +   chromosome_1_unplaced_Contig0.3951:379-486  107 0   107 gi|526117967|ref|NM_001281232.1|    1518    1236    1343    1   107 0   1236
212 1   0   0   0   0   0   0   -   chromosome_1_unplaced_Contig0.12366:214-427 213 0   213 gi|526117831|ref|NM_001281196.1|    1025    738 951 1   213 0   738
178 2   0   0   0   0   0   0   -   chromosome_1_unplaced_Contig0.12366:633-813 180 0   180 gi|526117831|ref|NM_001281196.1|    1025    558 738 1   180 0   558
243 1   0   0   0   0   0   0   -   chromosome_1_unplaced_Contig0.12366:909-1153    244 0   244 gi|526117831|ref|NM_001281196.1|    1025    314 558 1   244 0   314
313 1   0   0   0   0   0   0   -   chromosome_1_unplaced_Contig0.12504:1668-1887   314 0   314 gi|526117831|ref|NM_001281196.1|    1025    0   314 1   314 0   0

나는 새로운 요약 테이블 파일을 얻고 싶습니다.

탭 10에서 ":" 및 탭 14의 값이 동일한 새 행의 경우 탭 11이 해당 조합에 대해 합산됩니다. 이러한 조합이 한 번만 발생하는 행을 유지하고 싶습니다. 그러면 3개의 새로운 요약 탭이 제공됩니다. 그런 다음 이전 탭 15와 새 탭 3과 이전 탭 15의 차이점을 새 탭에 포함시키고 싶습니다. 출력은 다음과 같아야 합니다.

예제 출력:

old_tab_10  old_tab_14  sumof_old_tab11 old_tab15   (old_tab15)-(sumof_old_tab11)
chromosome_1_Contig0.1980   gi|952977790|ref|NM_001317128.1|    849 849 0
chromosome_1_Contig0.3916   gi|733214878|ref|NM_001303082.1|    477 708 231
chromosome_1_unplaced_Contig0.3951  gi|526117967|ref|NM_001281232.1|    107 1518    1411
chromosome_1_unplaced_Contig0.12366 gi|526117831|ref|NM_001281196.1|    637 1025    388
chromosome_1_unplaced_Contig0.12504 gi|526117831|ref|NM_001281196.1|    314 1025    711

나는 다음과 같은 것을 가지고 놀기 시작했습니다.

awk '{S[$14]+=$11;N[$14]+} END{for(i in S){print i, N[i]}}' 

그런 다음 이것이 내 능력 밖이라는 것을 깨달았습니다. ":"의 탭과 필드를 분리하는 것이 좋은 생각인지 또는 ":"을 분리하기 위해 다른 방법을 사용하는 것이 더 나은지조차 잘 모르겠습니다.

답변1

split다음을 사용하여 필드 10의 두 부분을 배열(여기서는 이라고 함 arr10) 로 추출 할 수 있습니다 .

split($10, arr10, ":")

그런 다음 배열의 첫 번째 요소와 전체 요소 14의 조합을 기반으로 인덱스를 작성할 수 있습니다. 해당 인덱스를 사용하면 다음 sum_of_11과 같은 두 개의 새로운 배열을 만들 수 있습니다 old_15.

sum_of_11[arr10[1]"\t"$14] += $11 # sum of all rows that have this index
old_15[arr10[1]"\t"$14] = $15     # just the value in the single most recent row

함께 정리(및 설정 OFS = "\t"):

awk '{ split($10, arr10, ":");
       sum_of_11[arr10[1]"\t"$14] += $11;
       old_15[arr10[1]"\t"$14] = $15
     } END {
       OFS = "\t";
       for (i in sum_of_11) {
         print i, sum_of_11[i], old_15[i], old_15[i] - sum_of_11[i]
       }
     }' file

결과:

chromosome_1_Contig0.3916   gi|733214878|ref|NM_001303082.1|    477 708 231
chromosome_1_unplaced_Contig0.12366 gi|526117831|ref|NM_001281196.1|    637 1025    388
chromosome_1_unplaced_Contig0.3951  gi|526117967|ref|NM_001281232.1|    107 1518    1411
chromosome_1_unplaced_Contig0.12504 gi|526117831|ref|NM_001281196.1|    314 1025    711
chromosome_1_Contig0.1980   gi|952977790|ref|NM_001317128.1|    849 849 0

답변2

사실, 당신은 올바른 길을 가고 있습니다. 그러나 데이터 구조에 대한 인덱스로 필드 10을 사용해야 합니다.

awk '{data[$10] = $14} END { for (d in data) print d " " data[d]; }'

여러 필드를 구별해야 하는 경우 다음과 같은 것을 사용하세요.

data[$10, "14"] = "x"; data[$10, "11"] = "y"

답변3

awk 파일로 사용

 { split($10,A,":") ;
  B[A[1]]=$14 ; C[A[1]] += $11  }
 END { for ( a in B ) printf "%s\t%s\t%d\n",a,B[a],C[a] ;}

주어진

chromosome_1_unplaced_Contig0.12366 gi|526117831|ref|NM_001281196.1|        637
chromosome_1_unplaced_Contig0.12504 gi|526117831|ref|NM_001281196.1|        314
chromosome_1_unplaced_Contig0.3951  gi|526117967|ref|NM_001281232.1|        107
chromosome_1_Contig0.1980   gi|952977790|ref|NM_001317128.1|        849
chromosome_1_Contig0.3916   gi|733214878|ref|NM_001303082.1|        477

다른 요구 사항을 이해하지 못합니다. 하지만

  • split($10,A,":")배열 A의 10번째 필드는 ":"를 기준으로 분할됩니다.
  • B[A[1]]=$14 ;매우 간단하다

프로그램 파일은 다음을 사용하여 호출됩니다.

awk -f se.awk data

관련 정보