Perl 选择性地将数组的元素合并到新数组的较少元素中

Perl 选择性地将数组的元素合并到新数组的较少元素中,perl,sequence,bioinformatics,fasta,bioperl,Perl,Sequence,Bioinformatics,Fasta,Bioperl,我在处理.fasta格式的DNA序列数据数组时遇到了一些问题。我特别想做的是获取一个有几千个序列的文件,并将文件中每个序列的序列数据邻接到文件中的一行。[Fasta格式是这样的:序列ID以>开头,之后该行上的所有内容都是一个描述。在下一行上,与该ID对应的序列存在。这可以无限期地持续到下一行以>开头,这是文件中下一个序列的ID]因此,在我的特定文件中,我的大多数序列都在多行上,因此我想做的是从本质上删除换行符,但只删除序列数据之间的新行,而不是序列数据和以>开头的序列ID行之间的新行 我这样做是

我在处理.fasta格式的DNA序列数据数组时遇到了一些问题。我特别想做的是获取一个有几千个序列的文件,并将文件中每个序列的序列数据邻接到文件中的一行。[Fasta格式是这样的:序列ID以>开头,之后该行上的所有内容都是一个描述。在下一行上,与该ID对应的序列存在。这可以无限期地持续到下一行以>开头,这是文件中下一个序列的ID]因此,在我的特定文件中,我的大多数序列都在多行上,因此我想做的是从本质上删除换行符,但只删除序列数据之间的新行,而不是序列数据和以>开头的序列ID行之间的新行

我这样做是因为我想通过length获得每个序列的序列长度,我相信这是最简单的方法,然后得到整个文件中所有序列的平均序列长度

到目前为止,我的脚本似乎不起作用:

#!/usr/bin/perl -w


##Subroutine
sub get_file_data1 { 
    my($filename) = $_[0];
    my @filedata = ();
    unless( open(GET_FILE_DATA, $filename)) {
    print STDERR "Cannot open file \"$filename\"\n\n";
    exit;
    }
    @filedata = <GET_FILE_DATA>;
    close GET_FILE_DATA;
    return @filedata;
}



##Opening files
my $fsafile = $ARGV[0];
my @filedata = &get_file_data1($fsafile);


##Procedure
my @count;
my @ids;
my $seq;

foreach $seq (@filedata){
        if ($seq =~ /^>/) {push @ids, $seq;
                                 push @count, "\n";
    }
        else {push @count, $seq;
    }
}


foreach my $line (@count) {
    if ($line =~ /^[AGTCagtc]/){
         $line =~ s/^([AGTCagtc]*)\n/$1/;
    }
}

##Make a text file to have a look
open FILE3, "> unbrokenseq.txt" or die "Cannot open output.txt: $!";

foreach (@count)
{
    print FILE3 "$_\n"; # Print each entry in our array to the file
}
close FILE3;


__END__
##Creating array of lengths
my $number;
my @numberarray;
foreach $number (@count) {
                push @numberarray, length($number);
                }
print @numberarray;


__END__
use List::Util qw(sum);

sub mean {
    return sum(@numberarray)/@numberarray;
}
程序部分的第二个foreach行出现了问题,我似乎无法理解它是什么。请注意,在结束行之后的代码我甚至还没有尝试过,因为我似乎无法在过程步骤中获得代码来执行我想要的操作。你知道我怎样才能得到一个包含完整序列元素的数组吗?我选择了从新数组中删除序列ID行。。?当我可以得到一个长度数组,之后我可以求平均值

最后,我应该遗憾地承认,我无法让Bio::Perl在我的计算机上工作,我已经尝试了几个小时,但错误超出了我的技能范围。我将与一位有希望帮助我解决Bio::perl问题的人交谈。但现在,我只能在没有它的情况下继续前进

谢谢!对不起,这篇文章太长了,我感谢你的帮助


Andrew

您的正则表达式专门捕获$1,但您正在将$打印到文件中。结果很可能不是您想要的结果。

请小心在s//中对角色组使用“*”或“贪婪”修饰符。您通常需要使用“+”来代替。“*”也将匹配不包含任何字符的行

带有“g”修饰符的搜索表达式也可以计算字符数。像这样:

$perl -e '$a="aggaacaat"; $b = $a =~ s/[a]//g; print $b; '
5
很酷吧!或者,在您的代码中,您可以对$1调用length


我吃惊地看到你的正则表达式中的逃逸'/n'。虽然它工作正常,但常用的“行尾”搜索词是“$”。这更便于携带,不会弄乱字符计数。

第二个循环的问题是,您实际上没有更改@count中的任何内容,因为$line包含@count中值的副本

但是,如果在第二个循环中要做的只是删除末尾的换行符,请使用chomp函数。有了这个,你就不需要第二个循环了。它也会比使用正则表达式更快

# remove newlines for all array elements before doing anything else with it
chomp @filedata;

# .. or you can do it in your first loop
foreach $seq (@filedata){
    chomp $seq;
    if ($seq =~ /^>/) {
    ...
}
另外一个提示:如果文件很大,使用get_file_data1将整个文件读入数组可能会很慢。在这种情况下,最好边走边迭代文件:

open my $FILE_DATA, $filename or die "Cannot open file \"$filename\"\n";
while (my $line = <$FILE_DATA>) {
    chomp $line;
    # process the record as in your Procedure section
    ...
}
close $FILE_DATA;

不,这部分代码是正确的。$\u是@count的每个元素的别名。非常感谢您的回复,我认为这绝对是一个不错的选择。尽管在进一步考虑之后,我认为我在这里遇到的最大问题是不能有选择地将数组的多个序列元素压缩为一个元素。我试图将与序列ID元素对应的所有序列数据元素(以>开头)压缩为一个元素。我天真地认为我可以通过删除序列元素后的新行来实现这一点,但这不起作用。。所以我想我必须完全重建这个。