서로 인접한 염색체를 기준으로 정렬된 파일 데이터 병합 - 컬럼 바이스

서로 인접한 염색체를 기준으로 정렬된 파일 데이터 병합 - 컬럼 바이스

chr position value 형식의 파일이 여러 개 있습니다.

"chr", "position", "samp1", "samp2", "samp3", "samp4" 형식으로 변환하고 싶습니다.

예를 들어:

샘플 1:

chr position value
1   3774318 1
1   3774319 1
1   3775200 2
1   3775201 7
1   3775202 70
1   3775203 7
1   3775204 270
1   3775205 3
1   3775206 5

샘플 2:

chr position value
1   3775200 1
1   3775201 1
1   3775202 10
1   3775203 1
1   3775204 12
1   3775205 1
1   3775206 13
1   3775207 1
1   3775208 1
1   3775209 18

(등...)

원하는 출력 파일: / 출력 파일에 임의의 값을 넣었습니다.

chr, position, value-samp1, value-samp2, value-samp3, value-samp4 
1 50204 2 17 5 2
1 50205 2 17 5 2
1 50206 2 18 5 2
1 50207 2 19 5 3
1 50208 3 19 5 3
1 50209 3 19 5 3

Join, merge, cat을 시도했지만 예상대로 작동하지 않았습니다. 나는 초보자입니다. 이 작업을 어떻게 수행할 수 있는지 아이디어가 있습니까?

(편집자 주: 귀하가 제공한 실제 데이터를 사용하여 설명한 작업의 예입니다.)

chr position    samp1   samp2
1   3774318     1       0
1   3774319     1       0
1   3775200     2       1
1   3775201     0       1
1   3775202     70      10
1   3775203     7       1
1   3775204     270     12
1   3775205     3       1
1   3775206     5       13
1   3775207     7       1
1   3775208     0       1
1   3775209     0       18

답변1

또 다른 awk방법. NA입력 파일 중 하나에 특정 변형이 존재하지 않는 경우 이 파일이 인쇄됩니다.

awk '{ if(FNR==1){files[fnum++]=FILENAME}else{var[$1"\t"$2][FILENAME]=$3}} END{ for(v in var){for(file in files){if(! var[v][files[file]]){var[v][files[file]]="NA"}}}printf "chr\tposition "; for(i=1;i<=fnum;i++){printf "value-samp%s\t",i;} print "";for(v in var){ printf "%s ",v; for(file in var[v]){if(file in var[v]); else{var[v][file]="NA";}  printf "%s\t", var[v][file] } print ""}}' s1 s2

또는 간결성을 그다지 좋아하지 않는 경우:

awk '{ 
        if(FNR==1){
            files[fnum++]=FILENAME
        }
        else{
            var[$1"\t"$2][FILENAME]=$3
        }
      } 
      END{ 
        for(v in var){
            for(file in files){
                if(! var[v][files[file]]){
                    var[v][files[file]]="NA"
                }
            }
        }
        printf "chr\tposition "; 
        for(i=1;i<=fnum;i++){
            printf "value-samp%s\t",i;
        } 
        print "";
        for(v in var){ 
            printf "%s ",v; 
            for(file in var[v]){
                if(file in var[v]); 
                else{
                    var[v][file]="NA";
                }
            printf "%s\t", var[v][file];
        } 
    print "";
    }
}' s1 s2

s1및를 s2사용 중인 실제 파일 이름으로 변경합니다. 샘플 입력에서 위 명령을 실행하면 다음이 반환됩니다.

chr position value-samp1    value-samp2 
1   3774318 1   NA  
1   3775200 2   1   
1   3774319 1   NA  
1   3775201 7   1   
1   3775202 70  10  
1   3775203 7   1   
1   3775204 270 12  
1   3775205 3   1   
1   3775206 5   13  
1   3775207 NA  1   
1   3775208 NA  1   
1   3775209 NA  18  

답변2

가져가다이 솔루션베이스와 같은 문제의 경우 원하는 결과를 얻으려면 미세 조정이 필요합니다. 이것은 답변이 아니며 단지 개요일 뿐이며 일부를 사용합니다.의사코드(sic?) 수행해야 할 작업을 간략하게 설명합니다.

리눅스 검토가입하다명령과그 능력성공적인 솔루션에 매우 중요합니다. 각 입력 파일은 결합하기 전에 특정 필드(여기에서는 염색체 번호가 사용됨, 필드 2)를 기준으로 정렬되어야 합니다.

조인은 두 개의 파일만 조인할 수 있기 때문에 조인을 여러 번 진행해야 하므로 일부 프로그래밍 구조와 제어 메커니즘이 필요합니다. 또한 지정한 공백(비어 있는) 값을 0으로 바꿔야 하므로 데이터 자체를 수정해야 합니다.

1) 첫 번째 데이터 파일을 다른 이름으로 복사하십시오.샘플_0

2) 각 라인을 확인하십시오샘플_0 필드 3의 값입니다. null인 경우 0으로 바꿉니다.

3) 초기화 값엑스데이터 파일의 번호와 일치하도록 합니다.

4) 각 데이터 파일을 연속적으로 사용하려면 for/next 루프를 만듭니다. 얼마나 많은 데이터 파일을 가지고 있나요? 글쎄, 실행할 때마다 스크립트를 편집할 필요 없이 이 작업을 수행하려면 for/next 루프를 사용하여 데이터 파일이 부족할 때까지 스크립트를 실행하십시오.

5) for/next 루프에서는 두 가지 작업을 수행합니다.

5A) 다음 파일의 각 줄에서 필드 3의 값을 확인합니다. null인 경우 0으로 바꿉니다.

5B) 실행가입하다페어링할 수 없는 회선을 포함합니다(-ㅏ옵션) 파일의 염색체 번호(필드 2)에샘플_0및 파일샘플_x 자동 서식 기능이 있습니다(옵션 사용).-o 자동) 따라서 두 파일에 데이터가 있는 염색체뿐만 아니라 모든 염색체에 대한 데이터 행을 병합합니다.샘플_0및 파일샘플_x. 파일에 출력 쓰기샘플_0.

6) 다른 데이터 파일이 있는 경우 추가엑스그런 다음 돌아가서 3)을 다시 수행하십시오. 모든 데이터 파일이 연결되면 완료되었으므로 for/next 루프를 종료합니다.

답변3

chr항상 1이면 무시해도 안전하기 때문에 지금은 무시하고 있습니다. 그렇지 않으면 OP에서 그것이 어떻게 맞는지 설명해야 합니다.

awk 'BEGIN {printf "position " }
        FNR>1{ 
        if (FNR==2) {nof+=1; printf ("%s%s " ,"Sam", nof )};
        pos[$2]=$2; data[$2, nof]=$3}
    END { printf "\n"; for (p in pos) {printf ("%s ", pos[p]); 
        for (d=1;d<=nof;d++) printf ("%s ", data[p,d]+0); print "\n"}
    }' file1 file2 | column -t

산출

position  Sam1  Sam2
3774318   1     0
3774319   1     0
3775200   2     1
3775201   7     1
3775202   70    10
3775203   7     1
3775204   270   12
3775205   3     1
3775206   5     13
3775207   0     1
3775208   0     1
3775209   0     18

송곳

첫 번째 열 머리글을 인쇄하여 시작하세요.

awk 'BEGIN {printf "position " }

모든 첫 번째 줄을 헤더로 무시합니다.

FNR>1{ 

각 파일의 두 번째 줄에서 파일 수를 늘리고 헤더를 인쇄합니다.

if (FNR==2) {nof+=1; printf ("%s%s " ,"Sam", nof )};

헤더 뒤의 각 줄에 대해 위치를 배열에 넣습니다 . 파일(샘플) 번호로 인덱스된 값을 포함하는 pos다른 배열을 설정합니다.datasampos

pos[$2]=$2; data[$2, nof]=$3}

모든 파일을 읽은 후 newline헤더에 a를 인쇄한 다음 pos각 위치를 반복적으로 인쇄합니다.

END { printf "\n"; for (p in pos ) {printf ("%s ", pos[p]); 

그런 다음 및 /file 번호 data로 인덱스된 배열을 반복하여 데이터가 없더라도 무언가가 인쇄되도록 null 값에 0을 추가한 다음 a를 인쇄합니다.psamdatanewline

for (d=1;d<=nof;d++) printf ("%s ", data[p,d]+0); print "\n"}

파일을 입력하고 출력을 파이프하여 column보기 좋게 만드세요.

}' file1 file2 | column -t

추가된 캐릭터다른 인덱스라고 가정

awk 'BEGIN {printf "chr position " }
        FNR>1{
        if (FNR==2) {nof+=1; printf ("%s%s " ,"Sam", nof )};
        chr[$1]=$1; pos[$2]=$2; data[$1, $2, nof]=$3}
    END { printf "\n"; for (c in chr) {for (p in pos ) {printf ("%s %s ", chr[c], pos[p]); 
        for (d=1;d<=nof;d++) printf ("%s ", data[c, p, d]+0); print "\n"}
    }}' file1 file2 | column -t

답변4

밀러 사용(https://github.com/johnkerl/miller) 당신은 실행할 수 있습니다

mlr --c2p --ifs ' '  --repifs \
sort -f chr,position,value \
then nest --implode --values --across-records -f value \
then nest --explode --across-fields --values -f value \
then unsparsify then clean-whitespace input0*.csv >output.csv

그리고 얻다

chr position value_1 value_2
1   3774318  1       -
1   3774319  1       -
1   3775200  1       2
1   3775201  1       7
1   3775202  10      70
1   3775203  1       7
1   3775204  12      270
1   3775205  1       3
1   3775206  13      5
1   3775207  1       -
1   3775208  1       -
1   3775209  18      -

노트:

  • 명령을 입력 파일의 이름에 맞게 조정해야 합니다. 내 예에서는input0*.csv
  • 진정한 CSV 출력을 원하면 --c2p으로 변경하세요 --csv.

관련 정보