我有一个制表符分隔文件,见下文: 第一列包含位置编号,1-end 其余的都有一些频率数字。
Position A B C D
1 117 0 1 0
2 4 0 0 16
3 0 5 11 0
4 0 0 0 5
5 0 15 0 0
6 100 0 108 0
7 0 0 147 0
我想将此文件重新格式化为两列,第一列是保持原样的位置列,第二列是每个位置的最高频率。
理想输出:
Position HighFreq
1 117
2 16
3 11
4 5
5 15
6 108
7 147
到目前为止我所拥有的是一个选择最高数字并打印的函数:
awk '{max=$1; for(i=2;i<=NF; i++) {if($i>max){max=$i;}};printf"%f\n",max}' file.tsv
我正在尝试为这个问题编写一个bash解决方案,但是非常欢迎Perl / Python!
答案 0 :(得分:3)
$ perl -MList::Util=max -F/\t/ -lane 'print join "\t", $. == 1 ? qw(Position HighFreq) : ( $F [0], max(@F[1..$#F]) )'
<强>解释强>
<强> -MList::Util=max
强>
加载List::Util::max
<强> -F/\t/ -a
强>
激活自动拆分并将分隔符设置为/\t/
<强> -lne
强>
自动附加相应的行结尾,应用单行,逐行处理ARGV
<强> print join "\t", ...
强>
打印标签分隔
<强> $. == 1 ? ... : ...
强>
处理栏目标题
<强> max( @F[1..$#F] )
强>
返回@F
答案 1 :(得分:0)
当你选择了Python标签时,可以在Python中完成,如下所示:
import sys
import csv
with open(sys.argv[1], 'rb') as f_input:
tsv = csv.reader(f_input, delimiter='\t')
next(tsv)
data = []
for row in tsv:
row = map(int, row)
data.append([row[0]] + [max(row[1:])])
with open(sys.argv[1], 'wb') as f_output:
tsv = csv.writer(f_output, delimiter='\t')
tsv.writerow(['Position', 'HighFreq'])
tsv.writerows(data)
答案 2 :(得分:0)
awk 'BEGIN{print"Position\tHighFreq"}{if(NR==1)next; max=0;for(i=2;i<=NF; i++) {if($i>max){max=$i;}} printf"%d\t%d\n",$1,max;}' file.tsv
输出:
Position HighFreq
1 117
2 16
3 11
4 5
5 15
6 108
7 147
答案 3 :(得分:0)
在Perl中
use strict;
use warnings 'all';
use feature 'say';
use autodie;
use List::Util 'max';
open my $fh, '<', 'freq.txt';
<$fh>;
say join "\t", qw/ Position HighFreq /;
while ( <$fh> ) {
my ($n, @fields) = split;
say join "\t", $n, max(@fields);
}
Position HighFreq
1 117
2 16
3 11
4 5
5 15
6 108
7 147