2012-03-14 4 views
3

시퀀스 또는 문자열에서 A, C 및 G의 개수를 계산하고 싶습니다. 다음 코드를 작성했습니다.tr /// 연산자를 사용하여 문자열의 문자 수를 계산하십시오.

그러나 값을 인쇄하면 A 만 인쇄됩니다. C와 G는 0으로 표시됩니다. 아래 코드에서 A의 첫 번째 점을 평가하고 있지만 C의 첫 번째 점을 평가하여 순서를 전환하면 C의 값을 얻지 만 이제 A와 G는 0으로 인쇄됩니다.

누구든지 내 코드에 어떤 문제가 있다고 말할 수 있습니까? 감사!

#! /usr/bin/perl 

use strict; 
use warnings; 

open(IN, "200BP_junctions_fasta.faa") or die "Cannot open the file: $!\n"; 
while(<IN>) 
    next if $_ =~ /\>/; 
    my $a = ($_ = tr/A//); 
    my $c = ($_ = tr/C//); 
    my $g = ($_ = tr/G//); 
    print "A:$a, C:$c, G:$g\n"; 
} 

파일은 다음과 같습니다 :

> A_Seq 
ATGCTAGCTAGCTAGCTAGTC 
> B_Seq 
ATGCGATCGATCGATCGATAG 

답변

6
$_ = tr/ $_ =~ tr/에 변경

. 또한 while의 열린 중괄호가 없습니다.

+0

감사합니다. 그건 신참 실수 였어. – Jordan

1

'C' 또는 'G'이 없으므로 '5'입니다. 귀하는 $_의 번역 값을 $_으로 지정하고 있습니다. ($_ =~ tr//)의 작업을 $_에 바인딩하면 원하는 결과를 얻을 수 있습니다.

하지만 실제로 을 컨텍스트 변수에 바인드에 바인딩 할 필요가 없습니다. 바인딩은 정규 표현식이나 변환 연산을 다른 변수에 적용 할 수 있도록하기 위해서입니다. 당신은 더 잘 쓰는 것 :

my $a = tr/A//; 
my $c = tr/C//; 
my $g = tr/G//; 

하지만 당신도 이런 식으로 작업을 수행 할 수 있습니다

$_{$_}++ foreach m/[ACG]/g; 
say "A:$_{A}, C:$_{C}, G:$_{G}"; 
0
open(IN, "input") or die "Cannot open the file: $!\n"; 
while(<IN>) { 
    next if $_ =~ /\>/; 
    my $a = @{[m/(A)/g]}; 
    my $c = @{[m/(C)/g]}; 
    my $g = @{[m/(D)/g]}; 
    print "A:$a, C:$c, G:$g\n"; 
} 
1

당신이 결합 연산자를 필요로 대답, =~을 대신 할당 operat0r의 , =이거나 기본 변수를 바인드 할 필요가 없다는 것을 의미합니다.

최근에, 나는 사물의 이러한 종류의에 대한 printf을 사용하고있다 :

while(<DATA>) { 
    next if /\>/; 
    printf "A:%s C:%s G:%s\n", tr/A//, tr/C//, tr/G//; 
    } 

가 나는 종종 tr/// 그래서 난 작동하지 않는이, 쓸 수 보간 수달라고했습니다

while(my $line = <DATA>) { 
    next if $line =~ /\>/; 
    print "Line is $_\n"; 
    printf "A:%s C:%s G:%s\n", map { $line =~ tr/$_// } qw(A C G); 
    } 

while의 기본 변수를 사용했다면, 나는 $_과 충돌하는 것에 대한 여분의 귀찮음을 느낍니다.나는 내가 eval을 할 수 알지만, 그건 번거 로움뿐만 아니라 더 있지만, l4m3 :

while(my $line = <DATA>) { 
    next if $line =~ /\>/; 
    print "Line is $_\n"; 
    printf "A:%s C:%s G:%s\n", map { eval "\$line =~ tr/$_//" } qw(A C G); 
    } 

내가하지만, 구현 세부 사항을 몰라도, 그래서 내가 때까지 서브 루틴이 이동할 수 XOR 문자열에 아마 영리한 방법있다

while(my $line = <DATA>) { 
    next if $line =~ /\>/; 
    print "Line is $line\n"; 
    printf "A:%s C:%s G:%s\n", map { count_bases($line, $_) } qw(A C G); 
    } 

sub count_bases { eval "\$_[0] =~ tr/$_[1]//" } 

당신이 tr///을 좋아하지 않아,하지만 난 적이없는 경우 : 별도의 서브 루틴 호출이 빅 데이터 munging 느려질 수 있지만, eval 제거하는 방법을 알아낼 수 그것을 파악할만큼 충분히 오래 추구했다. (당신이 이미하고있는 것보다 낫지는 않다.)

관련 문제