0
$\begingroup$

I try to find organism IDs used by UniProt (e.g. 9606 for "Homo sapiens") and information about the 'taxonomic kingdom' this organism belongs to. The only source on UniProt I could find is this file which contains all required information. So in the Python world it would be a dictionary of the form:

{org_id: {'name': 'org_name', 'kingdom': 'org_kingdom'}}

or a dataframe.

However, the file from above is not particular nice to parse due to its inconsistent column format (not impossible to parse though), so I am wondering whether there is an alternative source to retrieve this information or whether there is maybe even a webservice available that takes care of this parsing.

$\endgroup$

2 Answers 2

1
$\begingroup$

That file is actually trivial to parse. You only care about lines that have N=$species, so you can simply do:

sed -En 's/.* ([0-9]+): N=(.*)/\1\t\2/p' speclist 

That will return a tab separated list of taxID and species:

$ sed -En 's/.* ([0-9]+): N=(.*)/\1\t\2/p' speclist | head
648330  Aedes albopictus densovirus (isolate Boublik/1994)
10804   Adeno-associated virus 2
648242  Adeno-associated virus 2 (isolate Srivastava/1982)
118452  Abacion magnum
72259   Abaeis nicippe
102642  Abax parallelepipedus
392897  Abalistes stellaris
75332   Abbottina rivularis
515833  Abdopus aculeatus
56673   Antarctic bacterium DS2-3R

So to get human, for example, you could do:

$ sed -En 's/.* ([0-9]+): N=(.*)/\1\t\2/p' speclist | grep sapiens
63221   Homo sapiens neanderthalensis
9606    Homo sapiens

And, for exact matches:

$ sed -En 's/.* ([0-9]+): N=(.*)/\1\t\2/p' speclist | 
    awk -F'\t' '$2=="Homo sapiens"'
9606    Homo sapiens

If you also want to keep the taxon node (kingdom), you can use:

sed -En 's/.* ([A-Z])  *([0-9]+): N=(.*)/\1\t\2\t\3/p' speclist 

Which prints:

$ sed -En 's/.* ([A-Z])  *([0-9]+): N=(.*)/\1\t\2\t\3/p' speclist  | head
V   648330  Aedes albopictus densovirus (isolate Boublik/1994)
V   10804   Adeno-associated virus 2
V   648242  Adeno-associated virus 2 (isolate Srivastava/1982)
E   118452  Abacion magnum
E   72259   Abaeis nicippe
E   102642  Abax parallelepipedus
E   392897  Abalistes stellaris
E   75332   Abbottina rivularis
E   515833  Abdopus aculeatus
B   56673   Antarctic bacterium DS2-3R

The sed command might appear a little daunting if you don't know sed, but it's actually quite simple. The -E flag enables extended regular expressions which give us a simpler syntax. The -n suppresses normal output, so that sed won't actually print anything unless explicitly told to.

The s/from/to/ is the substitution operator and will replace from with to. Here, we are replacing zero or more characters (.*) until a space followed by one or more numbers ([0-9]+), a :, another space, then the string N= and then everything else (.*). The parentheses let us capture the matched strings, so that we can then refer to the 1st captured string as \1, the second as \2 etc. We are therefore replacing the entire line (because the regex matches the entire line) with the 1st pattern captured (the taxID, \1), a tab (\t) and the species name (\2). Finally, the p at the end means "print the resulting line if the substitution was successful", so only lines matching the desired pattern are actually printed.

$\endgroup$
2
  • $\begingroup$ Thanks, that helps already. Is there a quick way to also extract the taxonomic kingdom and store it in the third column? $\endgroup$
    – Cleb
    Commented Oct 27, 2017 at 17:24
  • 1
    $\begingroup$ @Cleb sure, see updated answer. Next time, please explain all these details in your question (I mean tell us exactly what information you want to extract) so we can give you a working answer directly. $\endgroup$
    – terdon
    Commented Oct 28, 2017 at 21:13
4
$\begingroup$

These are NCBI taxonomy ID's rather than anything specific to UniProt. One way to parse them would be using BioPython via Bio.Entrez, for example:

from Bio import Entrez

def get_taxon_name_from_NCBI_id(id_):
    Entrez.email = '[email protected]'
    handle = Entrez.efetch(db='taxonomy', id= id_, retmode='xml')
    records = Entrez.read(handle)[0]
    return records['ScientificName'], records['TaxId']

print(get_taxon_name_from_NCBI_id(9606))
# ('Homo sapiens', '9606')

Of course you could query Entrez directly: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=taxonomy&id=9606

Or even more basically do a manual search of NCBI taxonomy: https://www.ncbi.nlm.nih.gov/taxonomy/?term=9606

$\endgroup$
1
  • $\begingroup$ I was not precise enough in my question: What I am after are the IDs, so basically what you use as input and there associated name and taxonomic kingdom. Ideally it would be a dictionary of the form {org_id: {'name': 'org_name', 'kingdom': 'org_kingdom'}} but I guess I can easily do this directly from NCBI; thanks for making me aware of this! $\endgroup$
    – Cleb
    Commented Oct 27, 2017 at 17:23

Your Answer

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

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