2

我有一个文件:

1 Chr1       100820415  
1 Chr1       100821817  
1 Chr1       100821818  
1 Chr1       100823536  
1 Chr1       100824427  
2 Chr1       100824427  
2 Chr1       100824427  
1 Chr1       100824428

如果所有第 2 列相同且第 3 列值相同,我正在尝试添加第 1 列值。这有点像“集群”。

所以输出应该是:

1 Chr1       100820415  
1 Chr1       100821817  
1 Chr1       100821818  
1 Chr1       100823536  
5 Chr1       100824427
1 Chr1       100824428

我是新手awk并试图理解该语言,但是我不能说编写一个脚本if $2 is same then add $1 and if $2 is same then add $3 values (if $3 values are same)

这是我到目前为止所尝试的:

awk 'BEGIN{ x+=$1 } END {print x} if NF == $2' file_name

解决方案可以是 inawkpython

4

4 回答 4

3

一种方法awk

$ awk '{a[$2 OFS $3]+=$1}END{for(k in a)print a[k],k}' file
1 Chr1 100821817
1 Chr1 100821818
1 Chr1 100820415
5 Chr1 100824427
1 Chr1 100824428
1 Chr1 100823536

一种方法python

$ cat cluster.py
#!/usr/bin/env python
import fileinput

cluster = {}

for line in fileinput.input():
    field = line.strip().split()
    try:
        cluster[' '.join(field[1:])] += int(field[0])
    except KeyError:
        cluster[' '.join(field[1:])] = int(field[0])

for key, value in cluster.items():
    print value, key

使脚本可执行chmod +x cluster.py并运行如下:

$ ./cluster.py file
1 Chr1 100823536
1 Chr1 100821817
1 Chr1 100820415
5 Chr1 100824427
1 Chr1 100824428
1 Chr1 100821818

这两种方法在这里都使用了相同的技术,都利用了哈希表。我们使用awk关联数组和 python 字典。简单地说,两者都是数组,其中键不是数字而是字符串(第二和第三列值)。一个简单的例子:

blue 1
blue 2
red  5
blue 1
red  2

如果我们说awk '{a[$1]+=$2}' file,那么我们会得到以下信息:

Line    Array       Value  Explanation
1       a["blue"]   1      # Entry in 'a' is created with key $1 and value $2
2       a["blue"]   3      # Add $2 on line 2 to a["blue"] so the new value is 3
3       a["blue"]   3      # The key $1 is red so a["blue"] does not change
        a["red"]    5      # Entry in 'a' is created with new key "red"
4       a["blue"]   4      # Key "blue", Value 1, 1 + 3 = 4
        a["red"]    5      # Key "blue", so a["red"] doesn't change
5       a["blue"]   4      # Key "red", so a["blue"] doesn't change
        a["red"]    7      # Key "red", Value 2, 5 + 2 = 7
于 2013-10-02T18:45:53.510 回答
1

像这样的东西应该工作:

awk '{t1[$2$3] = $2; t2[$2$3] = $3; sums[$2$3] += $1}END{for (s in sums) print sums[s], t1[s], t2[s]}' input.txt
于 2013-10-02T18:11:43.807 回答
1

正是你想要的:

import re
from collections import defaultdict

d = defaultdict(int)

with open('file.txt') as f:
    for line in f:
        qty, chr, _id = re.split('\s+', line.strip())
        d[(_id, chr)] += int(qty)

for (_id, chr), qty in d.iteritems():
    print '{} {}       {}'.format(qty, chr, _id)
于 2013-10-02T19:15:14.657 回答
0

这是一个 Python 版本。

它从标准输入读取输入。

注意:它假定第二列总是Chr1,并保持输出按最后一列的值排序 - 它不会保留输入的顺序。

#!/usr/bin/env python2.7
import sys

# Maps a 'value' to its count
counter = {}

for line in sys.stdin:
    num, tag, value = line.split()
    num = int(num)
    counter[value] = counter.setdefault(value, 0) + num

for value in sorted(counter.keys()):
    print counter[value], 'Chr1', value
于 2013-10-02T18:29:34.577 回答