정의된 거리에 따라 SNP를 유전자좌로 그룹화합니다.

정의된 거리에 따라 SNP를 유전자좌로 그룹화합니다.

ID와 숫자(위치)가 포함된 정렬된 파일이 있습니다. 두 번째 열의 위치를 ​​500 간격으로 그룹화한 다음 다른 파일로 분할해야 합니다.

입력하다

snp00001    200
snp00002    300
snp00003    400
snp00004    500
snp00005    600
snp00006    900
snp00007    1500
snp00008    1800
snp00009    3000
snp00010    3500
snp00011    4000
snp00012    5000

원하는 출력

snp00001    200 Group1
snp00002    300 Group1
snp00003    400 Group1
snp00004    500 Group1
snp00005    600 Group1
snp00006    900 Group2
snp00007    1500    Group3
snp00008    1800    Group3
snp00009    3000    Group4
snp00010    3500    Group4
snp00011    4000    Group5
snp00012    5000    Group6

그런 다음 이러한 그룹을 별도의 파일에 저장하고 각각 및로 이름을 Group1바꿉니다 Group2.Group3Group4

다른 명령을 시도해 보았 bedtools으나 문제가 해결되지 않습니다.

어떤 도움이라도 대단히 감사하겠습니다.

감사합니다!

답변1

이것은 완벽한 직업입니다 awk.

$ awk -v step=500 -v OFS='\t' \
'{ 
    if(NR==1 || $2>limit){
        limit=$2+step
        group++
    } 
    file="Group"group; print $0,file 
}' input_file 
snp00001    200 Group1
snp00002    300 Group1
snp00003    400 Group1
snp00004    500 Group1
snp00005    600 Group1
snp00006    900 Group2
snp00007    1500    Group3
snp00008    1800    Group3
snp00009    3000    Group4
snp00010    3500    Group4
snp00011    4000    Group5
snp00012    5000    Group6

별도의 파일로 인쇄하려면:

awk -v step=500 -v OFS='\t' \
'{ 
    if(NR==1 || $2>limit){
        limit=$2+step
        group++
    } 
    file="Group"group; print $0,file > file
}' input_file 

Group1그러면 샘플 데이터에서 Group5다음 형식의 파일이 생성됩니다.

$ cat Group1 
snp00001    200 Group1
snp00002    300 Group1
snp00003    400 Group1
snp00004    500 Group1
snp00005    600 Group1

$ cat Group6
snp00012    5000    Group6

답변2

Perl + csplit을 사용하세요. 범위 연산자 또는 트리거 연산자 "..."

perl \
  -lMconstant='LIM,500' \
  -sane \
'
  my $e = do{$a=$F[1];1;} ... $F[1]-$a>LIM;

  print(qq($_\tGroup$k)),next
    if $e !~ /E0/ || $eof;

  print(q());$k++;

  redo if !eof || !$eof++;

' -- -k=1 file |
csplit --suppress-matched \
  -sz -f 'Group' - '/^$/' '{*}'

관련 정보