计算从拆分派生的项目数而不放入数组

时间:2016-06-08 03:45:52

标签: perl while-loop split count bioinformatics

我希望不遗余力地使用数组作为内存,但仍然可以获得while循环每次传递的split函数派生的项目数。
最终目标是根据序列的数量过滤输出文件,这可以通过文件的行数,出现的胡萝卜数或换行符数等来推断。 以下是我的代码:

    #!/usr/bin/perl
    use warnings; 
    use strict; 
    use diagnostics; 

    open(INFILE, "<", "Clustered_Barcodes.txt") or die $!;

    my %hash = ( 
            "TTTATGC" => "TATAGCGCTTTATGCTAGCTAGC",
            "TTTATGG" => "TAGCTAGCTTTATGGGCTAGCTA",
            "TTTATCC" => "GCTAGCTATTTATCCGCTAGCTA",
            "TTTATCG" => "AGTCATGCTTTATCGCGATCGAT",
            "TTTATAA" => "TAGCTAGCTTTATAATAGCTAGC",
            "TTTATAA" => "ATCGATCGTTTATAACGATCGAT",
            "TTTATAT" => "TCGATCGATTTATATTAGCTAGC",
            "TTTATAT" => "TAGCTAGCTTTATATGCTAGCTA",
            "TTTATTA" => "GCTAGCTATTTATTATAGCTAGC",
            "CTTGTAA" => "ATCGATCGCTTGTAACGATTAGC",
    );

    while(my $line = <INFILE>){ 
            chomp $line; 
            open my $out, '>', "Clustered_Barcode_$..txt" or die $!;
            foreach my $sequence (split /\t/, $line){
                    if (exists $hash{$sequence}){
                        print $out ">$sequence\n$hash{$sequence}\n";
                    } 
            }
    }

打开输入文件“Clustered_Barcodes.txt”,如下所示:

    TTTATGC TTTATGG TTTATCC TTTATCG
    TTTATAA TTTATAA TTTATAT TTTATAT TTTATTA
    CTTGTAA 

代码中将有三个输出文件,“Clustered_Barcode_1.txt”,“Clustered_Barcode_2.txt”和“Clustered_Barcode_3.txt”。输出文件的外观示例可能是第3个和最终文件,如下所示:

    >CTTGTAA 
    ATCGATCGCTTGTAACGATTAGC 

我需要一些方法来修改我的代码,以识别出现在文件中的行,胡萝卜或序列的数量,并将其用于文件的标题中。上述序列的新标题可能类似于“Clustered_Barcode_Number_3_1_Sequence.txt”

PS-我手动在上面的代码中做了哈希,试图让事情更简单。如果你想查看原始代码,请点击此处。输入文件格式如下:

   >TAGCTAGC 
    GCTAAGCGATGCTACGGCTATTAGCTAGCCGGTA  

以下是设置哈希的代码:

    my $dir = ("~/Documents/Sequences");          
    open(INFILE, "<", "~/Documents/Clustered_Barcodes.txt") or die $!; 

    my %hash = (); 

    my @ArrayofFiles = glob "$dir/*";            #put all files from the specified directory into an array

    #print join("\n", @ArrayofFiles), "\n";       #this is a diagnostic test print statement

    foreach my $file (@ArrayofFiles){                                 #make hash of barcodes and sequences
        open (my $sequence, $file) or die "can't open file: $!";        
        while (my $line = <$sequence>) {    
            if ($line !~/^>/){ 
                my $seq = $line; 
                $seq =~ s/\R//g;
                #print $seq;           
                $seq =~ m/(CATCAT|TACTAC)([TAGC]{16})([TAGC]+)([TAGC]{16})(CATCAT|TACTAC)/;  
                $hash{$2} = $3;                    
            }
        }
    } 

    while(<INFILE>){ 

3 个答案:

答案 0 :(得分:1)

您的哈希结构不适合您的问题,因为您有相同ID的多个条目。例如 TTTATAA 哈希ID在%哈希中有2个条目。

要解决此问题,请使用数组哈希来创建哈希。

中更改哈希创建代码
$hash{$2} = $3;

push(@{$hash{$2}}, $3);

现在在while循环中更改代码

while(my $line = <INFILE>){ 
        chomp $line; 
        open my $out, '>', "Clustered_Barcode_$..txt" or die $!;

        my %id_list;
        foreach my $sequence (split /\t/, $line){
            $id_list{$sequence}=1;

        }
        foreach my $sequence(keys %id_list)
        {
            foreach my $val (@{$hash{$sequence}})
            {
                    print $out ">$sequence\n$val\n";
            }
        }
}

答案 1 :(得分:1)

您可以使用正则表达式来计算:

$days

答案 2 :(得分:0)

我已经忘记了;

  1. 输出文件名称中的第一个数字是输入文件行号
  2. 输出文件名称中的第二个数字是输入文件列号
  3. 输入散列是数组的散列,以涵盖多个序列的情况&#34;匹配&#34;评论中提到的一个条形码
  4. 当条形码在散列中匹配时,输出文件将列出数组中的所有序列,每行一个。
  5. 我能看到的最简单的方法是使用临时文件名构建输出文件,并在拥有所有数据时重命名它。根据{{​​3}},创建临时文件的最简单方法是使用模块perl cookbook

    这个解决方案的关键是通过列索引而不是通常简单地遍历列表本身的perl方式来浏览出现在行上的条形码列表。为了获得实际的条形码,列号$col用于索引回@barcodes,这是通过在空格上划分行而创建的。 (请注意,File::Temp是由perl特殊设置的,用于模拟其前任之一的行为,awk(删除前导空格,拆分是在空白上,而不是单个空格)。

    这样我们就可以得到列号(从1索引)和我们可以从{{3}获得的行号。然后我们可以使用这些来使用内置的splitting on a single space重命名文件。

    use warnings;
    use strict;
    use diagnostics;
    use File::Temp qw(tempfile);
    
    open(INFILE, "<", "Clustered_Barcodes.txt") or die $!;
    
    my %hash = (
        "TTTATGC" => [ "TATAGCGCTTTATGCTAGCTAGC" ],
        "TTTATGG" => [ "TAGCTAGCTTTATGGGCTAGCTA" ],
        "TTTATCC" => [ "GCTAGCTATTTATCCGCTAGCTA" ],
        "TTTATCG" => [ "AGTCATGCTTTATCGCGATCGAT" ],
        "TTTATAA" => [ "TAGCTAGCTTTATAATAGCTAGC", "ATCGATCGTTTATAACGATCGAT" ],
        "TTTATAT" => [ "TCGATCGATTTATATTAGCTAGC", "TAGCTAGCTTTATATGCTAGCTA" ],
        "TTTATTA" => [ "GCTAGCTATTTATTATAGCTAGC" ],
        "CTTGTAA" => [ "ATCGATCGCTTGTAACGATTAGC" ]
    );
    
    my $cbn = "Clustered_Barcode_Number";
    my $trailer = "Sequence.txt";
    
    while (my $line = <INFILE>) {
        chomp $line ;
        my $line_num = $. ;
    
        my @barcodes = split " ", $line ;
        for my $col ( 1 .. @barcodes )  {
            my $barcode = $barcodes[ $col - 1 ];  # arrays indexed from 0
    
            # skip this one if its not in the hash
            next unless exists $hash{$barcode} ;
            my @sequences =  @{ $hash{$barcode} } ;
    
            # Have a hit - create temp file and output sequences
            my ($out, $temp_filename) = tempfile();
            say $out ">$barcode" ;
            say $out $_ for (@sequences) ;
            close $out ;
    
            # Rename based on input line and column
            my $new_name = join "_", $cbn, $line_num, $col, $trailer  ;
            rename ($temp_filename, $new_name) or
                warn "Couldn't rename $temp_filename to $new_name: $!\n" ;
        }
    }
    close INFILE
    

    示例输入数据中的所有条形码都在哈希中匹配,因此当我运行此时,我得到4行1行,5行2行,1行3行。

    Clustered_Barcode_Number_1_1_Sequence.txt
    Clustered_Barcode_Number_1_2_Sequence.txt
    Clustered_Barcode_Number_1_3_Sequence.txt
    Clustered_Barcode_Number_1_4_Sequence.txt
    Clustered_Barcode_Number_2_1_Sequence.txt
    Clustered_Barcode_Number_2_2_Sequence.txt
    Clustered_Barcode_Number_2_3_Sequence.txt
    Clustered_Barcode_Number_2_4_Sequence.txt
    Clustered_Barcode_Number_2_5_Sequence.txt
    Clustered_Barcode_Number_3_1_Sequence.txt
    

    Clustered_Barcode_Number_1_2_Sequence.txt例如:

    >TTTATGG
    TAGCTAGCTTTATGGGCTAGCTA
    

    Clustered_Barcode_Number_2_5_Sequence.txt有:

    >TTTATTA
    GCTAGCTATTTATTATAGCTAGC
    

    Clustered_Barcode_Number_2_3_Sequence.txt - 将哈希键与两个序列匹配 - 具有以下内容;

    >TTTATAT
    TCGATCGATTTATATTAGCTAGC
    TAGCTAGCTTTATATGCTAGCTA
    

    我在这里猜测当提供的条形码有两个匹配时你想要什么。希望有所帮助。