2013-10-02 34 views
2

分组帮助我有一个文件:集群或AWK

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

我想补充第1倍的值,如果所有列2是相同的,第3倍的值是相同的。这有点像'集群'。

所以输出应该是:

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 

解决方案可以是在awkpython

+0

你应该张贴你到目前为止试过了,还是你有一个具体的问题,而不仅仅是人们要解决的问题。 – Gray

+0

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

+0

我是awk的新手,试图理解物流,但是我无法说“如果$ 2是相同的,如果$ 2是相同的,那么增加$ 3的值(如果$ 3的值相同)对不起,作为一个免费的加载程序来临! – user2464553

回答

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) 
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 
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 
2

一种方式与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 
+0

感谢您的帮助!它的工作原理!然而,我可以理解你是如何表示只有在$ 2是相同的情况下才这么做的?我正试图理解你的一个班轮。请解释。 – user2464553

+0

@ user2464553我已经添加了散列表的解释。不要忘记通过点击旁边的勾号来注意所有有用的答案并接受最有用的答案。 –