如果计数少于5,则转换为N.A

时间:2018-10-09 17:09:44

标签: awk count

我有一个用空格分隔的大文件,其中包含成千上万的行和列。如果值的行数少于5,我想将其转换为N.A。

输入:

CHROM   108 139 159 265 350 450 461 559 765 850
SNP1    0   0   0   0   0   0   2   2   2   2
SNP2    2   2   2   2   2   0   0   0   0   0
SNP3    -1  -1  -1  -1  0   0   0   0   0   0
SNP4    0   0   0   -1  -1  2   2   2   2   2
SNP5    1   1   1   1   1   1   0   0   0   0

输出:

CHROM   108 139 159 265 350 450 461 559 765 850
SNP1    0   0   0   0   0   0   N.A N.A N.A N.A
SNP2    2   2   2   2   2   0   0   0   0   0
SNP3    N.A N.A N.A N.A 0   0   0   0   0   0
SNP4    N.A N.A N.A N.A N.A 2   2   2   2   2
SNP5    1   1   1   1   1   1   N.A N.A N.A N.A

我正在使用以下命令来实现所需的输出:

计算零计数:

awk -F'|' 'BEGIN{print "count", "lineNum"}{print gsub(/0/,"") "\t" NR}' input_ > output_1 

提取计数列:

awk '{print $1}' output_1 > output_1_col_1

与原始文件合并计数:

paste -d " " output_1_col_1 original_file > output_2

将值转换为计数少于5的N.A:

awk '$1 < 6{gsub("0","N.A")}1' output_2 > Final_output

类似地,我重复这些步骤来计算1、2和-1的计数。

有没有更好更快的方法来获得所需的输出?

2 个答案:

答案 0 :(得分:3)

通过文件一次:仍然需要遍历两次字段。

awk '
    FNR > 1 {
        delete count
        for (i=2; i<=NF; i++) count[$i]++
        for (i=2; i<=NF; i++) if (count[$i] < 5) $i = "N.A"
    }
    1
' file | column -t

答案 1 :(得分:2)

请您尝试以下。

awk '
FNR==1{
  if(++count==1){
    print
  }
  next
}
FNR==NR{
  for(i=2;i<=NF;i++){
    a[FNR,$i]++
  }
  next
}
{
  for(i=2;i<=NF;i++){
    $i=a[FNR,$i]<5?"N.A":$i
  }
}
1
'  Input_file  Input_file

输出如下。

CHROM   108 139 159 265 350 450 461 559 765 850
SNP1 0 0 0 0 0 0 N.A N.A N.A N.A
SNP2 2 2 2 2 2 0 0 0 0 0
SNP3 N.A N.A N.A N.A 0 0 0 0 0 0
SNP4 N.A N.A N.A N.A N.A 2 2 2 2 2
SNP5 1 1 1 1 1 1 N.A N.A N.A N.A