1

ヌクレオチド (文字列内の文字「A、T、G、C」) の出現回数をカウントしたい。これに演算子を使用しようとしましtr///たが、以下のコードでは毎回ゼロのカウントが返されます。

tr///これは、演算子内で変数を使用した場合にのみ発生します。個々の文字を個別に入力すると機能します。tr///パターンマッチング(およびカウント)のために演算子内で変数を使用できるかどうかを知りたかったのです。できれば、誰かが私のコードを変更する方法を教えてください。

後でコドンの数を数える予定です (~64)。したがって、トラブル。あなたの時間を大切にしてください。ありがとう!

#!/usr/bin/perl

use strict;
use warnings;

my $orf = "ATGCTAGCTAGCATAGAGCTAGCTA";
my @atgc = qw(A T G C);
my %hash = ();

foreach my $nt(@atgc) {
  $hash{$nt} = ($orf =~ tr/$nt//);
}
4

6 に答える 6

4

$" " には " "、" n"、または " t"のインスタンスがないATGCTAGCTAGCATAGAGCTAGCTAため、tr正しくゼロが返されます。

オペレーターを作成したい場合はtr///、それを解析してコンパイルする必要があります。

my %counts;
for my $nt (@atgc) {
   $counts{$nt} = eval "\$orf =~ tr/\Q$nt\E//";
}

しかし、私は使用しませんtr///

my %atgc = map { $_ => 1 } @atgc;
my %counts;
++$counts{$nt} for grep $atgc{$_}, split //, $orf;
于 2012-05-01T16:37:38.490 に答える
4

残念ながら、Perl は の検索リストに変数を補間しませんtr///。代わりに正規表現を使用する必要があります。

use strict;
use warnings;

my $orf = "ATGCTAGCTAGCATAGAGCTAGCTA";
my @atgc = qw(A T G C);
my %count;

$count{$1}++ while $orf =~ /([@atgc])/g;

printf "%s => %d\n", $_, $count{$_} for @atgc;

出力

A => 8
T => 6
G => 6
C => 5

注意してください

これは、文字列の配列のいずれかを照合するための一般的な解決策ではありません。起こっているのは、二重引用符で囲まれ@atcgた文字列にあるかのように、正規表現に補間されていることです。つまり、Perl は組み込み変数 (デフォルトでは単一のスペースに設定されています) を使用して、それを と同等の文字列に変換します。$"join $", @atgc

したがって、コードは実際には次のようになります

$count{$1}++ while $orf =~ /([A T G C])/g;

@atgcこれは、文字だけでなくスペースにも一致し、^]-.

不必要にスペースを数えることは問題ではありませんが、リストに記号が含まれている可能性がある場合、これは使用すべきソリューションではありません。

すべての ASCII 文字のカウントは、次のように安全に書くことができます。

$count{$1}++ while $orf =~ /(.)/sg;

ハッシュ内の不要な情報は%count単純に無視できます。

于 2012-05-01T16:37:39.193 に答える
3
$hash{$nt} = eval "\$orf =~ tr/\Q$nt\E//"

仕事をするべきです。たぶん、これは最も効果的な解決策ではありません。

于 2012-05-01T16:35:32.063 に答える
1

これを行うために正規表現などは必要ありません。文字列を歩くだけで済みます。

my $orf = "ATGCTAGCTAGCATAGAGCTAGCTA";
my %nt;

$nt{$_}++ foreach (split('', $orf));
于 2012-05-01T18:31:31.633 に答える
1

使用できますs///g

#!/usr/bin/env perl

use strict; use warnings;

my $orf = "ATGCTAGCTAGCATAGAGCTAGCTA";
my @atgc = qw(A T G C);

my %hash = map {$_ => $orf =~ s/$_/$_/g } @atgc;

出力:

---
あ:8
子:5
ガ:6
た:6

ソース文字列が非常に長くなる場合は、文字が ASCII であることが保証されていると仮定して、しばらくの間コンテンツを保持しているものとして扱い、一度に 1 バイトずつ読み取ることができます。

#!/usr/bin/env perl

use strict; use warnings;

my $orf = "ATGCTAGCTAGCATAGAGCTAGCTA";
my %atgc = map { $_ => undef } qw(A T G C);

use YAML;
print Dump count(\$orf, \%atgc);

sub count {
    my $src_ref = shift;
    my $lookup = shift;

    my %count;

    open my $src, '<', $src_ref or die $!;
    {
        local $/ = \1;
        exists $lookup->{$_} and $count{ $_ } += 1 while <$src>;
    }
    close $src;

    return \%count;
}
于 2012-05-01T17:40:49.343 に答える
1

パターン コンパイラを作成します。

sub make_counter {
  my @sequences = @_;

  my $pattern = "(?:" . join("|", map quotemeta, @sequences) . ")";

  my $compiled = eval q<
    sub {
      local($_) = @_;
      my $n = () = /$pattern/g;
    }
  >;

  if (defined $compiled) {
    return $compiled;
  }
  else {
    die "$0: internal: counter compilation failed:\n$@\n";
  }
}

を使用quotemetaすると、シーケンス内のすべての文字が、特別な意味を持たずに自分自身のみに一致するように強制されます。Perl FAQ のセクション 4 では、一致をカウントするためのファンキーなビットについて説明しています。

別のバージョンでは、リスト コンテキストでグローバル マッチを使用し、結果をスカラーに代入して、マッチ数のカウントを生成します。

$count = () = $string =~ /-\d+/g;

シーケンス内のジャンクを許容することに注意してください。たとえば、次のようにしてヌクレオチドを数えます。

my @nucleotides = qw/ G A T C /;

my $numnuc = make_counter @nucleotides;
print $numnuc->("xGxAxTxxxxTyA1C2A"), "\n";

出力:

7

でコドンを数えます

my @codons = qw(
  TTT TCT TAT TGT TTC TCC TAC TGC TTA TCA TAA TGA
  TTG TCG TAG TGG CTT CCT CAT CGT CTC CCC CAC CGC
  CTA CCA CAA CGA CTG CCG CAG CGG ATT ACT AAT AGT
  ATC ACC AAC AGC ATA ACA AAA AGA ATG ACG AAG AGG
  GTT GCT GAT GGT GTC GCC GAC GGC GTA GCA GAA GGA
  GTG GCG GAG GGG
);

my $numcod = make_counter @codons;
print $numcod->("GAG-GGG!AGG,TAT#TTT");

ジャンクが存在する場合は、コドン シーケンスに発生する必要があることに注意してください。

出力:

5
于 2012-05-01T19:37:02.980 に答える