创建一个以5为一组计算实例的文件

时间:2014-02-04 16:14:55

标签: r unix awk subset

我有一个看起来像这样的文件:

1   rs531842    503939  61733   G   A
1   rs10494103  35025   114771  C   T
1   rs17038458  254490  21116837    G   A
1   rs616378    525783  21127670    T   C
1   rs3845293   432526  21199392    A   C
2   rs16840461  233620  157112959   A   G
2   rs1560628   224228  157113214   T   C
2   rs17200880  269314  257145829   C   T
2   rs10497165  35844   357156412   C   T
2   rs7607531   624696  457156575   T   C

...第1列延伸至22,总共有数千个条目。

我想创建一个文件,列出第4列中有500万个数据库,这些数据库有数据,按第1列分隔。

基本上,除了第1列和第4列之外的所有内容都可以丢弃。一个简单的输入看起来像这样:

InputChr1:

61733
114771
21116837
21127670
21199392

InputChr2:

157112959
157113214
257145829 
357156412
457156575

因此,对于上面的示例,我希望得到两个看起来像这样的文件:

OutputChr1.txt

Start End Occurrences
1 5000000 2
20000001 25000000 3

OutputChr2.txt

Start End Occurrences
155000001 160000000 2 
255000001 260000000 1
355000001 360000000 1
455000001 460000000 1

有什么想法吗?在R中似乎应该可以使用lapply,但是我无法让for循环工作......

编辑:实际上,我认为这看起来比它需要的要难得多 - 基本上,我想将第1列拆分原始文件,在第4列中提取数据,然后在5百万的箱中计算实例。

(对于稍微随机的标签抱歉,只是想想哪些工具可能是最好的!)

2 个答案:

答案 0 :(得分:2)

嗯,这恰好是非常具有挑战性的。但是,我找不到使用唯一awk命令的方法。

awk -v const=5000000 -v max=150 
    '{a[$1,int($4/const)]++; b[$1]}
      END{for (i in b)
             {for (j=0; j<max; j++)
                   print i, j*const +1, (j+1)*const, a[i,j]
             }
         }' file

然后才得到结果:

awk 'NF==4'

解释

  • -v const=5000000 -v max=150给出变量。 const是分割结果的500万个值。 max是我们在END区块中查找信息的最大数字。
  • a[$1,int($4/const)]++创建一个以(1st field, 4th field)为索引的数组。注意第二个是int($4/const)是从23432获得 - &gt; 0,6000000 - &gt; 1,等等,就是看每个第4列的值块。
  • b[$1]跟踪已处理的第一列。
  • END{for (i in b) {for (j=0; j<max; j++) print j, j*const +1, (j+1)*const, a[i,j]}}'打印值。
  • awk 'NF==4'只打印那些包含4列的行。这样它只输出那些匹配的情况。

如果您想将值存储到新文件中,可以执行

awk 'NF==4 {print > "OutputChr"$1".txt}'

示例输出

$ awk -v const=5000000 -v max=150 '{a[$1,int($4/const)]++; b[$1]} END{for (i in b) {for (j=0; j<max; j++) print i, j*const +1, (j+1)*const, a[i,j]}}' a | awk 'NF==4'
1 1 5000000 2
1 20000001 25000000 3
2 155000001 160000000 2
2 255000001 260000000 1
2 355000001 360000000 1
2 455000001 460000000 1

答案 1 :(得分:0)

一体化

awk '{ v=int($4/const)
       a[$1 FS v]++
       min[$1]=min[$1]<v?min[$1]:v    # get the Minimum of column $4 for group $1
       max[$1]=max[$1]>v?max[$1]:v    # get the Minimum of column $4 for group $1
     }END{  for (i in min)
               for (j=min[i];j<=max[i];j++)  # set the for loop, and use the min and max value. 
                      if (a[i FS j]!="") print j*const+1,(j+1)*const,a[i FS j] > "OutputChr" i ".txt"      # if the data is exist, print to file "OutputChr" i ".txt" 
          }' const=5000000 file

结果:

$ cat OutputChr1.txt
1 5000000 2
20000001 25000000 3

$ cat OutputChr2.txt
155000001 160000000 2
255000001 260000000 1
355000001 360000000 1
455000001 460000000 1