根据定义的距离将 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

然后将这些组保存到不同的文件中,分别重命名为Group1Group2和。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' - '/^$/' '{*}'

相关内容