根据特定条件从表中选择行

时间:2014-12-17 16:37:54

标签: perl

我有一个包含五个制表符分隔列的表。该表最后提供。列“Name1”具有一个或多个“Name2”。每个“Name2”都有“Length”,“Score”和“Target(s)” 我必须根据以下标准只选择一个“Name2”及其对应的“Name1”。

(1)如果只有一种类型的“Name2”打印“Name1”,“Name2”,“Length”和“Score”。
(2)如果有两种或多种类型的“Name2”(来自相同的“Name1”),则比较“Name2”的目标。如果所有“Name2”中的目标集相同,则打印一个具有高“Score”的“Name2”。如果得分相同则打印具有最高“长度”的“名称2”。如果“得分”和“长度”相同,则使用“名称1”,“得分”和“长度”打印第一个“名称2”。

我编写的程序可以获取哈希中的所有表信息,但是我无法编写如何比较相同“Name1”的不同“Name2”的目标。我很感激如果有人可以帮助完成这些计划。非常感谢。 节目很兴奋“ ./Program.pl Inputfile.txt

(A)输入文件

Name1    Name2    Length    Score    Target    
sjj2_2RSSE.1    sjj2_2RSSE.1#II_15269285_15270181    897    3    WBGene00007064
sjj2_2RSSE.1    sjj2_2RSSE.1#II_15269295_15270191    897    4    WBGene00007064
sjj2_AC3.1    sjj2_AC3.1#V_10368996_10369727    732    3    WBGene00005532
sjj2_AC3.2    sjj2_AC3.2#V_10373256_10373988    733    3    WBGene00007070
sjj2_AC3.2    sjj2_AC3.2#V_10373256_10373988    733    3    WBGene00007028
sjj2_AC3.2    sjj2_AC3.2#V_10373256_10373988    733    3    WBGene00007019
sjj2_AC3.2    sjj2_AC3.2#V_10373256_10376356    3101    2    WBGene00007070
sjj2_AC3.2    sjj2_AC3.2#V_10373256_10376356    3101    2    WBGene00007028
sjj2_AC3.2    sjj2_AC3.2#V_10373256_10376356  3101    2    WBGene00007019
sjj2_AC3.6    sjj2_AC3.6#V_10393744_10394300    557    3    WBGene00000724
sjj2_AH10.1    sjj2_AH10.1#V_14146901_14148094    1194    4    WBGene00007082
sjj2_AH6.10    sjj2_AH6.10#II_9548665_9549674    1010    3    WBGene00003177
sjj2_AH6.10    sjj2_AH6.10#II_9548675_9549684    1010    2    WBGene00003177

(B)预期产出

Name1     Name2    Length    Score
sjj2_2RSSE.1    sjj2_2RSSE.1#II_15269295_15270191    897    4
sjj2_AC3.1    sjj2_AC3.1#V_10368996_10369727        732    3
sjj2_AC3.2    sjj2_AC3.2#V_10373256_10373988        733    3
sjj2_AC3.6    sjj2_AC3.6#V_10393744_10394300        557    3
sjj2_AH10.1    sjj2_AH10.1#V_14146901_14148094    1194    4
sjj2_AH6.10    sjj2_AH6.10#II_9548665_9549674    1010    3  

Program.pl

#!/usr/bin/perl
use Data::Dumper;


%data=();
@arraysiRNA=();
$i=0;
$file1=$ARGV[0];
open(FP1, $file1);
while($siRNA=<FP1>)
{
    chomp($siRNA);

    @aa=split(/\t/,$siRNA);
    ($clone_id,$amplicon_id,$amplicon_length,$amplicon_evidence,$amplicon_target)=split /\t/,$siRNA; 

    if(exists $data{$clone_id})
    {


        $data{$clone_id}{$amplicon_id}{amplicon_length}=$amplicon_length;
        $data{$clone_id}{$amplicon_id}{amplicon_evidence}=$amplicon_evidence;
        push( @{ $data{$clone_id}{$amplicon_id}{amplicon_target}}, $amplicon_target);

    }
    else
    {
    $data{$clone_id}{$amplicon_id}{amplicon_length}=$amplicon_length;
    $data{$clone_id}{$amplicon_id}{amplicon_evidence}=$amplicon_evidence;
    push( @{ $data{$clone_id}{$amplicon_id}{amplicon_target}}, $amplicon_target);
    }

    $i++;
}


#print Dumper(\%data);  


foreach $Name1 (keys %data)
{
    foreach $Name2 (keys %{$data{$Name1}})
    {
    $len=$data{$Name1}{$Name2}{amplicon_length};
    $evid=$data{$Name1}{$Name2}{amplicon_evidence};
    @tar=@{$data{$Name1}{$Name2}{amplicon_target}};
        #select only unique targets
    @uniqueTar = do { my %seen; grep { !$seen{$_}++ } @tar };
    print "$Name1\t$Name2\tamplicon_length= $len\n";
    print "amplicon_evidence= $evid\n";
    print "amplicon_target= @tar\n";
    print "amplicon_target uniq= @uniqueTar\n";

    }
}



close FP1;

1 个答案:

答案 0 :(得分:1)

这里的技巧是能够快速知道嵌套哈希中有多少个键或数组元素。我经常使用这种模式。

scalar keys %{ $hash{$key} }

scalar @{ $hash{$key} }

返回元素数量。因此,如果您想查看散列键是否只有1个子键:

if (scalar keys %{ $hash{$key} } == 1) {

使用此模式,您现在可以检查已定义的案例。

您定义了两种情况:

  1. 克隆有1个扩增子

  2. 克隆有多个扩增子,所有扩增子都有相同的靶标

  3. 对于案例2,在第24和31行添加以下内容:

    $data2{$clone_id}{'amplicons'}{$amplicon_target} = 1;
    

    现在只需添加另一个循环进行分析(这会在转储之后替换你的底部循环)。

    foreach my $clone (keys %data) {
    
        # case 1, clone only has 1 amplicon
        if (scalar keys %{$data{$clone}} == 1) {
    
    
        } else {
    
            # case 2, clone has >1 amplicon but all have same target
            if (scalar keys %{$data2{$clone}{'amplicons'} == 1) {
    
            }
    
        }
    }