2
$\begingroup$

Hi I am looking to sort a list of kmers into descending order. I used KMC to obtain a list of kmers from a fastq file separated by tab (e.g.; kmer count). From there I have written this python script to attempt to sort the kmers and their counts in descending order:

import csv

with open("6mers.tsv") as kmer_file:
    
    tsv_reader = csv.DictReader(kmer_file, delimiter="\t")
    
    for kmer in tsv_reader:
        
        name = kmer["kmer"]
        
        count = kmer["count"]
        
        # section below attempts to sort the dictionary into descending order
        # taken from (https://www.freecodecamp.org/news/sort-dictionary-by-value-in-python/) 
        sorted_kmers = sorted(kmer.items(), key=lambda x:x[1], reverse=True)

        converted_dict = dict(sorted_kmers)
    
        print(converted_dict)

The code above outputs this:

{'kmer': 'TGCCAA', 'count': '2'}
{'kmer': 'TGGACA', 'count': '2'}
{'kmer': 'TGGGAA', 'count': '2'}
{'kmer': 'TGGTAA', 'count': '5'}
{'kmer': 'TGTCAA', 'count': '5'}
{'kmer': 'TGTGAA', 'count': '2'}
{'kmer': 'TTCCAA', 'count': '13'}
{'kmer': 'TTGAAA', 'count': '6'}
{'kmer': 'TTGCAA', 'count': '4'}
{'kmer': 'TTTAAA', 'count': '6'}

Clearly I am creating a separate dictionary for each kmer and it's count - I'm not sure how but I would like a result that looks more like this:

{'TTCCAA', '13'}
{'TTGAAA', '6'}
{'TTTAAA', '6'}
{'TGGTAA', '5'}
{'TGTCAA', '5'}
{'TTGCAA', '4'}
{'TGCCAA', '2'}
{'TGGACA', '2'}
{'TGGGAA', '2'}
{'TGTGAA', '2'}

Can someone help me fix my code so it works?

EDIT:

The .tsv file looks just like this:

TGCCAA  2
TGGACA  2
TGGGAA  2
TGGTAA  5
TGTCAA  5
TGTGAA  2
TTCCAA  13
TTGAAA  6
TTGCAA  4
TTTAAA  6
$\endgroup$

2 Answers 2

2
$\begingroup$

Just make sure to cast the count to an integer prior to sorting. Assuming you need to do something with the counts, you could use:

import csv

from operator import itemgetter
from pprint import pprint


with open("6mers.tsv") as kmer_file:

    reader = csv.reader(kmer_file, delimiter="\t")
    counts = ((kmer, int(count)) for kmer, count in reader)

    sorted_kmers = sorted(counts, key=itemgetter(1), reverse=True)

    pprint(sorted_kmers)

Results:

[('TTCCAA', 13),
 ('TTGAAA', 6),
 ('TTTAAA', 6),
 ('TGGTAA', 5),
 ('TGTCAA', 5),
 ('TTGCAA', 4),
 ('TGCCAA', 2),
 ('TGGACA', 2),
 ('TGGGAA', 2),
 ('TGTGAA', 2)]
$\endgroup$
1
  • $\begingroup$ This works! Thank you! $\endgroup$
    – rimo
    Feb 1 at 21:21
1
$\begingroup$

This is untested code ... without seeing to the raw file its tricky. Could you try:

import csv
with open("6mers.tsv") as kmer_file:
    tsv_reader = csv.DictReader(kmer_file, delimiter="\t")
    mydict = {rows[0]:rows[1] for rows in tsv_reader if not rows[0] == 'kmer'}

sorted_kmers = sorted(mydict.items(), key=lambda x:x[1], reverse=True)
print(sorted_kmers)

I'm assuming there is a header called 'kmer'


The output didn't work. The rows['kmers'] infers that (somehow) tsv_reader is already a dictionary (that's not how I thought it worked). Thus try,

import csv
with open("6mers.tsv") as kmer_file:
    tsv_reader = csv.DictReader(kmer_file, delimiter="\t")
    mydict = {rows['kmers']:rows['count'] for rows in tsv_reader}

sorted_kmers = sorted(mydict.items(), key=lambda x:x[1], reverse=True)
print(sorted_kmers)

Unless it's loaded as a singular dictionary with Kmer as the key and count as the value the sort line will not work. Once that format is achieved as a dictionary then it will work.

What I don't understand is where it's getting 'kmer' or 'count' from if there are no headers in the csv file. Something isn't right if the above code works.

$\endgroup$
10
  • $\begingroup$ I tried the code you wrote but I got this error message: Traceback (most recent call last): File ~/opt/anaconda3/lib/python3.9/site-packages/spyder_kernels/py3compat.py:356 in compat_exec exec(code, globals, locals) File ~/Desktop/new_try/untitled1.py:12 mydict = {rows[0]:rows[1] for rows in tsv_reader} File ~/Desktop/new_try/untitled1.py:12 in <dictcomp> mydict = {rows[0]:rows[1] for rows in tsv_reader} KeyError: 0 $\endgroup$
    – rimo
    Jan 31 at 21:23
  • $\begingroup$ There was a header that I manually added with "kmer" and "count" but the raw result file from KMC does not include that header so I want to try and do it without the header added in $\endgroup$
    – rimo
    Jan 31 at 21:24
  • $\begingroup$ I don't know why it's not working! It's so strange. I tried a different IDE just to make sure there wasn't a a bug with the one I was using but it really isn't working with either of them... $\endgroup$
    – rimo
    Jan 31 at 21:46
  • $\begingroup$ does "rows[0]" look for a specific instance of 0 in the keys? $\endgroup$
    – rimo
    Jan 31 at 21:48
  • 1
    $\begingroup$ @M__ You can just pass in a list of fieldnames, e.g. csv.DictReader(kmer_file, fieldnames=['kmer', 'count'], delimiter="\t") $\endgroup$
    – Steve
    Feb 1 at 0:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.