我试图编写一个 Perl 脚本来比较两个 DNA 序列(可以说每个长度为 60 个字符)对齐,然后显示序列彼此匹配与不匹配的比率。但我运气不太好。如果它有帮助我可以上传我的代码,但它没有用。这是我试图在下面实现的示例。
例如
A T C G T A C
| | | | | | |
T A C G A A C
所以上面例子的匹配项是 4。不匹配项是:3。给它一个 4.3 的比率。
任何帮助将非常感激。谢谢。
我试图编写一个 Perl 脚本来比较两个 DNA 序列(可以说每个长度为 60 个字符)对齐,然后显示序列彼此匹配与不匹配的比率。但我运气不太好。如果它有帮助我可以上传我的代码,但它没有用。这是我试图在下面实现的示例。
例如
A T C G T A C
| | | | | | |
T A C G A A C
所以上面例子的匹配项是 4。不匹配项是:3。给它一个 4.3 的比率。
任何帮助将非常感激。谢谢。
Here is an approach which gives a NULL, \0, for each match in an xor
comparison.
#!/usr/bin/perl
use strict;
use warnings;
my $d1='ATCGTAC';
my $d2='TACGAAC';
my $len = length $d1; # assumes $d1 and $d2 are the same length
my $matches = () = ($d1 ^ $d2) =~ /\0/g;
printf "ratio of %f", $matches / ($len - $matches);
Output: ratio of 1.333333
只需获取其中一个字符串的长度(我们假设字符串长度相等,对吗?),然后使用substr
.
my @strings = ( 'ATCGTAC', 'TACGAAC' );
my $matched;
foreach my $ix ( 0 .. length( $strings[0] ) - 1 ) {
$matched++
if substr( $strings[0], $ix, 1 ) eq substr( $strings[1], $ix, 1 );
}
print "Matches: $matched\n";
print "Mismatches: ", length( $strings[0] ) - $matched, "\n";
通常我会说“你试过什么”和“先上传你的代码”,因为这似乎不是一个非常困难的问题。但让我们试一试:
创建两个数组,一个用于保存每个序列:
@sequenceOne = ("A", "T", "C", "G", "T", "A", "C");
@sequenceTwo = ("T", "A", "C", "G", "A", "A", "C");
$myMatch = 0;
$myMissMatch = 0;
for ($i = 0; $i < @sequenceOne; $i++) {
my $output = "Comparing " . $sequenceOne[$i] . " <=> " . $sequenceTwo[$i];
if ($sequenceOne[$i] eq $sequenceTwo[$i]) {
$output .= " MATCH\n";
$myMatch++;
} else {
$myMissMatch++;
$output .= "\n";
}
print $output;
}
print "You have " . $myMatch . " matches.\n";
print "You have " . $myMissMatch . " mismatches\n";
print "The ratio of hits to misses is " . $myMatch . ":" . $myMissMatch . ".\n";
当然,您可能希望即时从其他内容中读取序列,而不是对数组进行硬编码。但你明白了。使用上面的代码,您的输出将是:
torgis-MacBook-Pro:platform-tools torgis$ ./dna.pl
Comparing A <=> T
Comparing T <=> A
Comparing C <=> C MATCH
Comparing G <=> G MATCH
Comparing T <=> A
Comparing A <=> A MATCH
Comparing C <=> C MATCH
You have 4 matches.
You have 3 mismatches
The ratio of hits to misses is 4:3.
有很多方法可以做到这一点。这是一个。
use strict;
use warnings;
my $seq1 = "ATCGTAC";
my $seq2 = "TACGAAC";
my $len = length $seq1;
my $matches = 0;
for my $i (0..$len-1) {
$matches++ if substr($seq1, $i, 1) eq substr($seq2, $i, 1);
}
printf "Length: %d Matches: %d Ratio: %5.3f\n", $len, $matches, $matches/$len;
exit 0;
我认为这substr
是要走的路,而不是将字符串拆分为数组。
如果作为子例程呈现,这可能是最方便的:
use strict;
use warnings;
print ratio(qw/ ATCGTAC TACGAAC /);
sub ratio {
my ($aa, $bb) = @_;
my $total = length $aa;
my $matches = 0;
for (0 .. $total-1) {
$matches++ if substr($aa, $_, 1) eq substr($bb, $_, 1);
}
$matches / ($total - $matches);
}
输出
1.33333333333333
一般来说,请发布您的代码。它确实有帮助。无论如何,这样的事情应该做你所要求的:
#!/usr/bin/perl -w
use strict;
my $d1='ATCGTAC';
my $d2='TACGAAC';
my @dna1=split(//,$d1);
my @dna2=split(//,$d2);
my $matches=0;
for (my $i=0; $i<=$#dna1; $i++) {
$matches++ if $dna1[$i] eq $dna2[$i];
}
my $mis=scalar(@dna1)-$matches;
print "Matches/Mismatches: $matches/$mis\n";
请记住,尽管 4 比 3 的比率肯定不是4.3 而是 ~1.3。如果您发布有关输入文件格式的一些信息,我将更新我的答案以包括用于解析文件中的序列的行。
比尔·鲁珀特说得对,有很多方法可以做到这一点。这是另一个:
use Modern::Perl;
say compDNAseq( 'ATCGTAC', 'TACGAAC' );
sub compDNAseq {
my $total = my $i = 0;
$total += substr( $_[1], $i++, 1 ) eq $1 while $_[0] =~ /(.)/g;
sprintf '%.2f', $total / ( $i - $total );
}
输出:
1.33