인쇄

2016-12-04 1 views
0

내가 파일 1에서 값이 출력 파일을 생성하고 파일을 1에서 2인쇄

라인을 제기 할 다른 파일에서 값을 해시 :

chr1 커프스 엑손 708,356 708,487 1,000 -.
gene_id "CUFF.3"; transcript_id "CUFF.3.1"; exon_number "5"; FPKM "3.1300591420"; frac "1.000000"; conf_lo "2.502470"; conf_hi "3.757648"; cov "7.589085"; chr1 커프스 단추 엑손 708356 708487. -. gene_id "XLOC_001284"; transcript_id "TCONS_00007667"; exon_number "7"; gene_name "LOC100288069"; o"CUFF.15.2"; nearest_ref "NR_033908"; class_code "j"; tss_id "TSS2981";

파일 (2)로부터 라인 :

CUFF.48557
CHR4 : 160253850-160259462 : 160259621-160260265 : 160260507-160262715가

이 파일에서 두 번째 열이 고유 id (uniq_id). transcript_id (CUFF_id) uniq_id gene_id 내 스크립트가 첫 번째 파일에서 XLOC_ID 및 FPKM 값을 사용하고, 두 번째에서 두 개의 열이와 함께 인쇄

(XLOC_ID) FPKM :

나는 다음과 같은 형식의 출력 파일을 얻으려면 파일.

#!/usr/bin/perl -w 

use strict; 

my $v_merge_gtf = shift @ARGV or die $!; 
my $unique_gtf = shift @ARGV or die $!; 

my %fpkm_hash; 
my %xloc_hash; 

open (FILE, "$v_merge_gtf") or die $!; 
while (<FILE>) { 
    my $line = $_; 
    chomp $line; 
    if ($line =~ /[a-z]/) { 
     my @array = split("\t", $line); 
     if ($array[2] eq 'exon') { 
      my $id = $array[8]; 
      if ($id =~ /transcript_id \"(CUFF\S+)/) { 
       $id = $1; 
       $id =~ s/\"//g; 
       $id =~ s/;//; 
      } 

      my $fpkm = $array[8]; 
      if ($fpkm =~ /FPKM \"(\S+)/) { 
       $fpkm = $1; 
       $fpkm =~ s/\"//g; 
       $fpkm =~ s/;//; 
      } 

      my $xloc = $array[17]; 
      if ($xloc =~ /gene_id \"(XLOC\S+)/) { 
       $xloc = $1; 
       $xloc =~ s/\"//g; 
       $xloc =~ s/;//; 
      } 
      $fpkm_hash{$id} = $fpkm; 
      $xloc_hash{$id} = $xloc; 
     } 
    } 
} 

close FILE; 


open (FILE, "$unique_gtf") or die $!; 
while (<FILE>) { 
    my $line = $_; 
    chomp $line; 
    if ($line =~ /[a-z]/) { 
     my @array = split("\t", $line); 
     my $id = $array[0]; 
     my $uniq = $array[1]; 
     print $id . "\t" . $uniq . "\t" . $xloc_hash{$id} . "\t" . $fpkm_hash{$id} . "\n"; 
    } 
} 

close FILE; 

나는 파일의 외부 해시를 초기화하지만 각 커프 값에 대해 다음과 같은 오류가 발생합니다 :

CUFF.24093
chr17 : 3533641-3539345 : 3527526-3533498 : 3526786-3527341을 (.) ex_1.pl 라인 55 라인 9343.

사용에 연결하거나 문자열의 초기화되지 않은 값의 3524707-3526632

사용 ex_1.pl 라인 (55)에 연결 (.) 또는 문자열의 초기화되지 않은 값, 라인의 9343.

어떻게이 문제를 해결할 수 있습니까?

감사합니다.

+0

어디까지입니까? – simbabque

+0

혼란을 드려 죄송합니다. 오류는 인쇄 문의 행을 참조합니다. print $ id. "\ t". $ uniq. "\ t". $ xloc_hash {$ id}. "\ t". $ fpkm_hash {$ id}. "\엔"; –

+0

음, 값 중 하나가 초기화되지 않았습니다. 어떤거야? 어쩌면 입력 데이터가 일치하지 않을 수도 있습니다. – simbabque

답변

0

경고 메시지는 $id 키 (CUFF.24093)가 두 번째 파일의 9343 라인이 첫 번째 파일에서 만든 해시에 포함되어 있지 않기 때문에 발생한다고 생각합니다.

두 번째 파일의 ID가 첫 번째 파일에 포함되지 않았습니까? 그것은 여기의 경우 인 것처럼 보인다.이것은 다음과 같은 print 문을 우회과의 정상에 다시 갈 것

my $id = $array[0]; 
my $uniq = $array[1]; 

next unless exists $fpkm_hash{$id}; # add this line 

print $id . "\t" . $uniq . "\t" . $xloc_hash{$id} . "\t" . $fpkm_hash{$id} . "\n"; 

:

그렇다면, 당신은 그냥이 알 수없는 ID를 건너하려면, 당신은 같은 프로그램에 한 줄을 추가 할 수 있습니다 while 루프를 반복하고 다음 행을 읽고 처리를 계속하십시오.

알 수없는 ID가 발생하는 경우 수행 할 작업에 따라 다릅니다.

업데이트 : 나는 당신의 코드를 관찰/향상시킬 수있을 것이라고 생각했습니다.

my $v_merge_gtf = shift @ARGV or die $!; 
my $unique_gtf = shift @ARGV or die $!; 

오류 변수 $! (이것은 내가 최근에 펄을 사용 후에도 십사년 발견 된 사실이다) 여기에 어떤 목적을 제공하지 않습니다. $!은 운영 체제와 관련된 시스템 호출에만 설정됩니다. 가장 많이 사용되는 파일은 open이며 파일의 경우 닫고 디렉토리의 경우 opendir 및 closedir입니다. 파일 또는 디렉토리 열기/닫기에 오류가 발생하면 $!에 오류 메시지가 포함됩니다. (포함 된 코드에서 내가 어떻게 처리했는지 확인하십시오. shift이 성공하지 못하면 $usage 메시지를 작성했습니다.

2 개의 해시를 사용하여 정보를 저장하는 대신 1 개의 해시 인 %data을 사용했습니다. 장점은 적은 메모리를 사용한다는 것입니다 (2가 아니라 1 세트의 키만 저장하기 때문에). 그러나 원하는 경우 2를 사용할 수 있습니다.

여는 3 개의 인수 (filehandle, mode, filename)를 사용했습니다. (여기서 자세히 설명하지 않기 때문에) 여기에 자세히 설명하지 않기 때문에, 어휘 파일 핸들 my $mrgmy $unique은을 사용하는 대신 파일 핸들을 생성하는 새로운 방법입니다. 귀하의 2 열을위한).

while 루프에서 $line에 직접 할당 할 수 있습니다 (예 : while (my $line = <FILE>)). 샘플 프로그램에서는 $line에 할당하지 않고 기본 변수 $_에 의존했습니다. (이것은 2 개의 다음 문장을 단순화합니다, next unless /\S/; my @array = split /\t/;). 첫 번째 파일에 대해서는 chomp을 사용하지 않았습니다. 왜냐하면 문자열 내부를 파싱하고 문자열의 끝에서 아무 것도 사용하지 않기 때문입니다. 두 번째 변수 my $uniq = ...chomp에 의해 제거되지 않으면 그 끝에 끝에 개행 문자가 있기 때문에 while 루프의 경우 chomp이 필요합니다.

나는이 진술 내용의 의미를 모르겠다. if ($line =~ /[a-z]/). 빈 줄을 확인하고 비 공백 데이터 만 처리하려고한다고 가정합니다. 그래서 나는 next unless /\S/;을 썼다. (다음 문장을 건너 뛰고 while 루프의 맨 위로 가서 다음 레코드를 읽음).

입력 파일에 오류가 없어 처음 while 루프가 작동했습니다. 오류가있는 경우 코드 작성 방법이 문제 일 수 있습니다.

my $id = $array[8]; 문은 다음 if 문이 거짓 일 때 잘못 입력 된 값인 $id을 제공합니다. (캡처하려는 다른 변수 2 개에 대해서도 마찬가지입니다. $fpkm$xloc). 내 코드 예제에서 어떻게 처리했는지 확인할 수 있습니다.

내 코드에서 일치하지 않으면 사망했습니다. die은 아니지만 match or next이라고 말하면 다음 데이터 행을 시도 할 수 있습니다. 그것은 당신이 실패한 매치를 어떻게 처리하길 원하는지에 달려 있습니다. (당신이 당신의 대체에 그랬던 것처럼)

음을

그리고이 라인 $array[8] =~ /gene_id "(CUFF\S+)";/에서

, 나는 캡처 된 데이터를 다음 ";를 넣어 사용한다는 점에 유의 캡처 된 데이터에서 제거 할 필요가 없다, 나는 이것을 알고 귀하의 코드에 대한 긴 의견이지만, 왜 내가 변경 사항을 권장했는지에 대한 좋은 아이디어를 얻길 바랍니다.

or die "Could not find ID in $v_merge_gtf (line# $.)";

$.

파일의 행 번호를 읽을 수 있습니다.

#!/usr/bin/perl 
use warnings; 
use strict; 

my $usage = "USAGE: perl $0 merge_gtf_file unique_gtf_file\n"; 

my $v_merge_gtf = shift @ARGV or die $usage; 
my $unique_gtf = shift @ARGV or die $usage; 

my %data; 

open my $mrg, '<', $v_merge_gtf or die $!; 

while (<$mrg>) { 
    next unless /\S/; 
    my @array = split /\t/; 
    if ($array[2] eq 'exon') { 

     $array[8] =~ /gene_id "(CUFF\S+)";/ 
      or die "Could not find ID in $v_merge_gtf (line# $.)"; 
     my $id = $1; 

     $array[8] =~ /FPKM "(\S+)";/ 
      or die "Could not find FPKM in $v_merge_gtf (line# $.)"; 
     my $fpkm = $1; 

     $array[17] =~ /gene_id "(XLOC\S+)";/ 
      or die "Could not find XLOC in $v_merge_gtf (line# $.)"; 
     my $xloc = $1; 

     $data{$id}{fpkm} = $fpkm; 
     $data{$id}{xloc} = $xloc; 
    } 
} 
close $mrg or die $!; 


open my $unique, '<', $unique_gtf or die $!; 
while (<$unique>) { 
    next unless /\S/; 
    chomp; 
    my ($id, $uniq) = split /\t/; 
    print join("\t", $id, $uniq, $data{$id}{fpkm}, $data{$id}{xloc}), "\n"; 
} 

close $unique or die $!; 
+0

귀중한 제안에 감사드립니다. $ id 대신 transcript_id 대신 gene_id를 사용했습니다. 그 시점에서 해시의 $ id와 배열의 $ id가 일치하기 시작하여 오류가 수정되었습니다. –

+0

@Olha Kholod 많은 정보로 내 게시물에 대한 업데이트를 추가했습니다. –

+0

코드를 한 줄씩 설명해 주셔서 감사합니다. 본인의 시간과 노력에 감사 드리며 대부분의 진술에 동의합니다. 프로그래밍에 익숙하지 않아 업데이트 할 때 제안 할 때 내 줄의 복잡성이 줄어들 수 있습니다. 앞으로이 문제를 극복하기 위해 자신의 기술을 향상 시키려고 노력할 것입니다. –