如果操作员在里面循环

时间:2015-11-19 14:06:15

标签: bioinformatics gawk

我输入文件如下所示,需要为每3列三元组执行此转换col1*0 + col2*1 + col3*2

input.txt - 所有正数,可以是小数,真实文件有1000列。

0 0 0 1 0 0
0 1 0 0 0 1
0 0 1 0 0 0

我有以下gawk专栏:

gawk '{for(i=1;i<=NF;i+=3)x=(x?x FS:"")(($(i+1))+($(i+2)*2));print x;x=y}' input.txt
0 0
1 2
2 0

此外,我需要检查3个数字是否全为零,如果它们都是零,则转换应为-9

伪代码:

if($i==0 & $(i+1)==0 & $(i+2)==0) {-9} else {$(i+1)+$(i+2)*2}
#or as all numbers are positive.
if(($i+$(i+1)+$(i+2))==0) {-9} else {$(i+1)+$(i+2)*2}

预期产出:

-9 0
1 2
2 -9

数据描述 该数据来自IMPUTE2软件 - 基因型插补和单倍型定相计划。行是SNP,列是样本。每个SNP由3列表示。每个SNP 3个数字,范围0-1(等位基因AA AB BB的概率)。因此,在上面的例子中,我们有3个SNP和2个样本。插补也可以表示为剂量值,每个SNP 1个数,范围0-2。我们试图将概率格式转换为剂量格式。当IMPUTE2无法向任何等位基因提供任何概率时,它会输出0 0 0,然后我们应该转换为无调用-9

2 个答案:

答案 0 :(得分:4)

如果三个给定列为0,您希望总和不同。为此,您可以将三元运算符展开为类似&gt;

的运算符
gawk '{ for(i=1;i<=NF;i+=3) {
          x=$(i+1) + $(i+2)*2;   # the sum
          res=res (res ? FS : "") ($i==0 && $(i+1)==0 && $(i+2)==0 ?-9:x)
        }
       print res; res=""         # print stored line and empty for next loop
      }' file

也就是说,如果所有元素都是-9,则附加值0。否则,计算出的x

res=res (res ? FS : "") ($i==0 && $(i+1)==0 && $(i+2)==0 ?-9:x)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   ^
                           if three columns are 0..........|

如果所有值均为正数,则可以重新格式化检查以仅比较总和是否为0

($i + $(i+1) + $(i+2)) ? x : -9

使用您的文件进行测试显然有效:

$ gawk '{for(i=1;i<=NF;i+=3) {x=$(i+1) + $(i+2)*2; res=res (res ? FS : "") ($i==0 && $(i+1)==0 && $(i+2)==0 ?-9:x)} print res; res=""}' file
-9 0
1 2
2 -9

答案 1 :(得分:2)

另一个$ awk '{c1=$2+2*$3;c2=$5+2*$6; print c1||$1?c1:-9,c2||$4?c2:-9}' lop -9 0 1 2 2 -9 单行(假设非负输入值)

{{1}}