for 循环中的 If 运算符
If operator inside for loop
我有如下输入文件,需要对每 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 software - a genotype imputation and haplotype phasing program. Rows are SNPs 输出的,列是样本。每个 SNP 由 3 列表示。每个 SNP 有 3 个数字,范围为 0-1(等位基因 AA AB BB 的概率)。所以在上面的例子中我们有 3 个 SNP 和 2 个样本。插补也可以表示为剂量值,每个 SNP 1 个数字,范围为 0-2。我们正在尝试将概率格式转换为剂量格式。当 IMPUTE2 不能给任何等位基因任何概率时,它输出为 0 0 0
,那么我们应该转换为 no call -9
.
如果给定的三个列是 0
,您希望总和不同。为此,您可以将三元运算符扩展为 >
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
即如果所有元素都是0
,则追加值-9
。否则,计算出的 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
另一个awk
单行(假设非负输入值)
$ awk '{c1=+2*;c2=+2*; print c1||?c1:-9,c2||?c2:-9}' lop
-9 0
1 2
2 -9
我有如下输入文件,需要对每 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 software - a genotype imputation and haplotype phasing program. Rows are SNPs 输出的,列是样本。每个 SNP 由 3 列表示。每个 SNP 有 3 个数字,范围为 0-1(等位基因 AA AB BB 的概率)。所以在上面的例子中我们有 3 个 SNP 和 2 个样本。插补也可以表示为剂量值,每个 SNP 1 个数字,范围为 0-2。我们正在尝试将概率格式转换为剂量格式。当 IMPUTE2 不能给任何等位基因任何概率时,它输出为 0 0 0
,那么我们应该转换为 no call -9
.
如果给定的三个列是 0
,您希望总和不同。为此,您可以将三元运算符扩展为 >
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
即如果所有元素都是0
,则追加值-9
。否则,计算出的 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
另一个awk
单行(假设非负输入值)
$ awk '{c1=+2*;c2=+2*; print c1||?c1:-9,c2||?c2:-9}' lop
-9 0
1 2
2 -9