Perl 对齐序列中缺失数据的插补
我想要一个简单的perl脚本,可以帮助我估算对齐序列中缺失的核苷酸:例如,我的旧_文件包含以下对齐序列:Perl 对齐序列中缺失数据的插补,perl,Perl,我想要一个简单的perl脚本,可以帮助我估算对齐序列中缺失的核苷酸:例如,我的旧_文件包含以下对齐序列: seq1 ATGTC seq2 ATGTC seq3 ATNNC seq4 NNGTN seq5 CTCTN 所以我现在想推断文件中的所有N,并得到一个新文件,其中所有N都是根据特定位置的多数核苷酸推断出来的。我的新文件应如下所示: seq1 ATGTC seq2 ATGTC seq3 ATGTC seq4 ATGTC seq5 CTCTC 脚本用法:impute_missing_dat
seq1
ATGTC
seq2
ATGTC
seq3
ATNNC
seq4
NNGTN
seq5
CTCTN
所以我现在想推断文件中的所有N,并得到一个新文件,其中所有N都是根据特定位置的多数核苷酸推断出来的。我的新文件应如下所示:
seq1
ATGTC
seq2
ATGTC
seq3
ATGTC
seq4
ATGTC
seq5
CTCTC
脚本用法:impute_missing_data.pl old_file new_file或任何其他方法对我都有帮助。
谢谢。以下是我评论中的脚本,格式更为可读:
use warnings;
use strict;
my (@data, $counts, @max);
#read in the file
while (<>) {
chomp;
next if /seq/;
my @sings = split //;
for (my $i = 0; $i < @sings; $i++) {
$counts->[$i]{$sings[$i]}++ if $sings[$i] ne 'N';
}
push (@data, \@sings);
}
# get most freq letters
foreach my $col (@$counts) {
my ($max, $maxk) = (0, '');
foreach my $cell (keys %$col) {
if ($col->{$cell} > $max) {
($max, $maxk) = ($col->{$cell}, $cell);
}
}
push (@max, $maxk);
}
# substitute Ns with most freq letters
foreach (my $i = 0; $i < @data; $i++) {
my $row = $data[$i];
for (my $i = 0; $i < @$row; $i++) {
if ($row->[$i] eq 'N') {
$row->[$i] = $max[$i];
}
}
print "seq".($i+1)."\n".join("", @$row), "\n";
}
#!/usr/bin/perl
use strict;
my @stat;
while(<>) {
print and next if /^seq/;
chomp;
my @seq = split //;
for my $i (0..$#seq){
my ($e, %s) = ($seq[$i], %{$stat[$i]}); # read-only aliases
if($e=~/N/){
my $substitution = [sort {$s{$a} <=> $s{$b}} keys %s]->[-1];
$seq[$i] = $substitution;
warn "substituted N with $substitution in col $i, count $s{$substitution}\n";
} else {
$stat[$i]->{$e}++;
}
}
print @seq, "\n"';
}
或
这似乎是必需的
use strict;
use warnings;
use Fcntl 'SEEK_SET';
open my $fh, '<', 'old_file' or die $!;
my @counts;
while (<$fh>) {
next if /[^ATGCN\s]/;
my $i = 0;
$counts[$i++]{$_}++ for /[ATGC]/g;
}
for my $maj (@counts) {
($maj) = sort { $maj->{$b} <=> $maj->{$a} } keys %$maj;
}
seek $fh, 0, SEEK_SET;
while (<$fh>) {
s/N/$counts[pos]/eg unless /[^ATGCN\s]/;
print;
}
你是否需要某个特定部分的帮助,或者你只是希望有人为你编写整个脚本?如果是后者,有各种各样的外包资源,如odesk.com等,你可以雇佣一个人来为你完成任务。我看到Joel在一小时前发布的建议得到了感谢,但没有看到你在两小时前回复的答案被接受,谢谢Borodin。如果答案对你有用,你应该接受它。如果你不知道怎么做,你应该尽快查看FAQ。这里有一个简短但有点难看的解决方案:perl-w-ne'print和next If/^seq/;咀嚼@seq=拆分/;对于我的$i 0..$seq{my$e,%s=$seq[$i],%{$stat[$i]};如果$e=~/N/{$seq[$i]=[sort{$s{$a}$s{$b}键%s]->[-1];在列$i中用$seq[$i]替换N,则计数$s{$seq[$i]}\N}否则{$s{$i[$i>]]-{$e}使用类似于字符的数据结构打印@seq、[-N}>。这个解决方案删除了seqN标签并替换它们,假设它们是连续的,从1开始,每隔一行出现一次。这是期待一个简短的例子,谢谢博罗丁。我目前正在尝试此解决方案。此解决方案根本不起作用。除非正确初始化@stat,否则无法将未定义的值用作哈希引用-这应该是我的@stat=map+{map{$\u=>0}qwA C G t},0。。4.此外,它仅基于当前行之前的数据而不是整个文件设置N的值
my @stat = map +{map {$_ => 0} qw(A C G T)} 0..4;
use strict;
use warnings;
use Fcntl 'SEEK_SET';
open my $fh, '<', 'old_file' or die $!;
my @counts;
while (<$fh>) {
next if /[^ATGCN\s]/;
my $i = 0;
$counts[$i++]{$_}++ for /[ATGC]/g;
}
for my $maj (@counts) {
($maj) = sort { $maj->{$b} <=> $maj->{$a} } keys %$maj;
}
seek $fh, 0, SEEK_SET;
while (<$fh>) {
s/N/$counts[pos]/eg unless /[^ATGCN\s]/;
print;
}
seq1
ATGTC
seq2
ATGTC
seq3
ATGTC
seq4
ATGTC
seq5
CTCTC