" NotImplementedError:SeqRecord"当在使用SeqIO解析的fasta文件上使用sorted时

时间:2017-02-21 10:55:12

标签: python bioinformatics biopython fasta

我试图按照文件中序列的字母顺序(而不是序列的ID)对fasta文件进行排序。 fasta文件包含200多个序列,我试图在一个位主控(使用python代码)中找到重复项(通过重复,我的意思是几乎相同的蛋白质序列,但不是相同的ID)。 所以我想从fasta文件中创建一个字典,然后对字典的值进行排序。 我试图使用的代码如下:

"Traceback (most recent call last):
  File "sort.py", line 4, in <module>
    print sorted(my_dict.values())
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Bio/SeqRecord.py", line 730, in __lt__
    raise NotImplementedError(_NO_SEQRECORD_COMPARISON)
NotImplementedError: SeqRecord comparison is deliberately not implemented. Explicitly compare the attributes of interest."

我不断收到此消息错误:

<jsp-config>   
    <jsp-property-group id="defaultUtf8Encoder">
        <url-pattern>*.jsp</url-pattern>
        <page-encoding>UTF-8</page-encoding>
    </jsp-property-group>     
</jsp-config>

我也试图寻找如何完成这个错误,但是有很多关于这个的信息,我读到的很少有信息显然说存储在字典字典中的序列长度可能有问题? ...如果是这样,如何在没有SeqIO的情况下对fasta文件进行排序?

2 个答案:

答案 0 :(得分:2)

mata所述,您需要将关键功能传递给sorted

from Bio import SeqIO
import operator
input_file = open("example.fasta")    
my_dict = SeqIO.to_dict(SeqIO.parse(input_file, "fasta"))
for r in sorted(my_dict.values(), key=operator.attrgetter('seq')):
    print r.id, str(r.seq)

返回:

seq3 ABCDEFG
seq0 ABCWYXO
seq2 BCDEFGH
seq1 IJKLMNOP

现在,为了你想要完成的事情。如果您按字母顺序对200个序列进行排序,则仍需要手动扫描列表以查找近似重复项。这很容易出错,所以最好为此编写一些代码。

在计算机科学中,edit distance是一种通过计算将一个字符串转换为另一个字符串所需的最小操作数量来量化两个字符串(例如,单词)之间的差异的方法。

此算法有多种实现可用。我们将从this answer获取一个。

def levenshteinDistance(s1, s2):
    if len(s1) > len(s2):
        s1, s2 = s2, s1

    distances = range(len(s1) + 1)
    for i2, c2 in enumerate(s2):
        distances_ = [i2+1]
        for i1, c1 in enumerate(s1):
            if c1 == c2:
                distances_.append(distances[i1])
            else:
                distances_.append(1 + min((distances[i1], distances[i1 + 1], distances_[-1])))
        distances = distances_
    return distances[-1]

现在我们需要确定两个序列可能有多不相似(多少次插入/切除/替换)的阈值。然后我们成对比较FASTA文件中的每两个序列:

from Bio import SeqIO
from itertools import combinations
input_file = open("example.fasta")    

treshold = 4
records = SeqIO.parse(input_file, "fasta")
for record1, record2 in combinations(records, 2):
    edit_distance = levenshteinDistance(str(record1.seq), str(record2.seq))
    if edit_distance <= treshold:
        print "{} and {} differ in {} characters".format(record1.id, record2.id, edit_distance)

这给出了:

seq0 and seq3 differ in 4 characters
seq2 and seq3 differ in 2 characters

答案 1 :(得分:1)

以下是另一种消除基于bioawkfastq-tools(以及awkuniq的fasta文件重复项的方法,这些文件通常存在于任何类似UNIX的文件中命令行环境):

bioawk -c fastx '{print "@"$name"\n"$seq"\n+\n"$seq}' test.fasta \
    | fastq-sort -s \
    | bioawk -c fastx '{print $name"\t"$seq}' \
    | uniq -f 1 \
    | awk '{print ">"$1"\n"$2}'

bioawkawk的修改版本,有助于操纵某些常见的生物信息格式。

第一行将数据转换为fastq格式,因为fastq-sort可以使用这些格式。 -c fastx选项告诉bioawk将数据解析为fasta或fastq。这定义了可以在命令中使用的$name$seq字段。我们使用$seq字段作为虚拟质量来获得有效的fastq格式。

第二行告诉fastq-sort(来自fastq-tools)按顺序排序数据(选项-s)。

第三行使用bioawk提取名称和序列,并将它们作为两个以制表符分隔的字段,以便在每条记录的一行中包含相关信息。

第四行使用uniq来消除在比较连续行时忽略第一个字段的重复项(如果我正确理解了我刚刚发现的-f选项的含义)。如果我对uniq的理解是正确的,那么融合记录的名称将是同一序列系列中第一条记录的名称。

第五行使用awk将制表符分隔的字段重新格式化为fasta。

我在我的一些数据上测试了这种方法,它似乎有效。