Q.and has asked for the wisdom of the Perl Monks concerning the following question:

I have BLAST tabular output with an added second column, such that each line of the data looks like:

[0] queryspecies [1] subjspecies [2] subjID [3] percentidentity ...

The query species column contains multiple species and was blast against a multi-species database; column 2, subject species is non-unique, but the identifier for that subject species sequence in the 3rd col is unique.

For each query species, I want to return the subject identifier with the highest percent identity out of all those with the same subject species--query species pair.

I think this will involve a hash of hashes, using query species as keys for subject species, whose values are subject identifiers, plus some conditional evaluation of the percent identity and somewhere to store the highest percent ID. I'm not sure how to begin writing this, but would prefer to do so without using BioPerl. Any guidance would be of great assistance!

Mock Input:

qspecies1  subjectspecies1  subjsp1.seqA  30
qspecies1  subjectspecies1  subjsp1.seqB  90
qspecies1  subjectspecies1  subjsp1.seqC  100
qspecies1  subjectspecies1  subjsp1.seqD  40
qspecies1  subjectspecies2  subjsp2.seqA  100
qspecies1  subjectspecies2  subjsp2.seqB  12
qspecies2  subjectspecies1  subjsp1.seqD  30
qspecies2  subjectspecies1  subjsp1.seqE  90
qspecies2  subjectspecies2  subjsp2.seqC  10
qspecies2  subjectspecies2  subjsp2.seqD  70
qspecies2  subjectspecies3  subjsp3.seqA  80

Desired Output:

qspecies1  subjectspecies1  subjsp1.seqC  100
qspecies1  subjectspecies2  subjsp2.seqA  100
qspecies2  subjectspecies1  subjsp1.seqE  90
qspecies2  subjectspecies2  subjsp2.seqD  70
qspecies2  subjectspecies3  subjsp3.seqA  80
  • Comment on Parsing multispecies database BLAST output

Replies are listed 'Best First'.
Re: Parsing multispecies database BLAST output
by poj (Abbot) on Mar 24, 2016 at 20:09 UTC
    #!perl use strict; my %hash=(); while (<DATA>){ my ($spec,$sub,$id,$pc) = split; push @{$hash{$spec}{$sub}},[$id,$pc]; } for my $spec (sort keys %hash){ for my $sub (sort keys %{$hash{$spec}}){ my @f = sort {$b->[1] <=> $a->[1]} @{$hash{$spec}{$sub}}; printf "%s %s %s %s\n",$spec,$sub,@{$f[0]}; } }
    poj
      Excellent, thanks so much!
Re: Parsing multispecies database BLAST output -- oneliner
by Discipulus (Canon) on Mar 25, 2016 at 08:25 UTC
    A oneliner is enough
    #cat subspecies.txt qspecies1 subjectspecies1 subjsp1.seqA 30 qspecies1 subjectspecies1 subjsp1.seqB 90 qspecies1 subjectspecies1 subjsp1.seqC 100 qspecies1 subjectspecies1 subjsp1.seqD 40 qspecies1 subjectspecies2 subjsp2.seqA 100 qspecies1 subjectspecies2 subjsp2.seqB 12 qspecies2 subjectspecies1 subjsp1.seqD 30 qspecies2 subjectspecies1 subjsp1.seqE 90 qspecies2 subjectspecies2 subjsp2.seqC 10 qspecies2 subjectspecies2 subjsp2.seqD 70 qspecies2 subjectspecies3 subjsp3.seqA 80 # # #perl -MData::Dump -lanE "$hash{$F[0]}{$F[1]}=[$F[2],$F[3]] unless $ha +sh{$F[0]}{$F[1]}[1]>$F[3];END{dd%hash}" subspecies.txt ( "qspecies2", { subjectspecies1 => ["subjsp1.seqE", 90], subjectspecies2 => ["subjsp2.seqD", 70], subjectspecies3 => ["subjsp3.seqA", 80], }, "qspecies1", { subjectspecies1 => ["subjsp1.seqC", 100], subjectspecies2 => ["subjsp2.seqA", 100], }, )

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.