2012-08-14 2 views
0

유전자 세트와 기존 유전자 쌍이 주어지면, 나는 이미 존재하지 않는 새로운 쌍의 유전자를 생성하려고합니다.생성 된 무작위 쌍이 이미 존재하지 않는 것을 확인하는 숫자 목록에서 무작위 쌍을 생성하십시오.

유전자 파일의 형식은 다음과 같습니다

123  
134 
23455 
3242 
3423 
... 
... 

유전자 쌍 파일의 형식은 다음과 같습니다

12,345  
134,23455 
23455,343 
3242,464452 
3423,7655 
... 
... 

을하지만 난 여전히 known_interactions와 new_pairs 사이의 몇 가지 일반적인 요소를 얻을. 오류가 어디 있는지 모르겠습니다. 인수에 대한

,
펄 generate_random_pairs.pl entrez_genes_file known_interactions_file
250000 내가 번호 250000 내가 프로그램을 생성 할 얼마나 많은 임의 쌍 알려주는 것이다 15880.의 공통 요소를 가지고.

#! usr/bin/perl 

use strict; 
use warnings; 

if (@ARGV != 3) { 
    die "Usage: generate_random_pairs.pl <entrez_genes> <known_interactions> <number_of_interactions>\n"; 
} 
my ($e_file, $k_file, $interactions) = @ARGV; 

open (IN, $e_file) or die "Error!! Cannot open $e_file\n"; 
open (IN2, $k_file) or die "Error!! Cannot open $k_file\n"; 

my @e_file = <IN>; s/\s+\z// for @e_file; 
my @k_file = <IN2>; s/\s+\z// for @k_file; 

my (%known_interactions); 

my %entrez_genes; 
$entrez_genes{$_}++ foreach @e_file; 

foreach my $line (@k_file) { 
    my @array = split (/,/, $line); 
    $known_interactions{$array[0]} = $array[1]; 
} 
my $count = 0; 

foreach my $key1 (keys %entrez_genes) { 
    foreach my $key2 (keys %entrez_genes) { 
     if ($key1 != $key2) { 
      if (exists $known_interactions{$key1} && ($known_interactions{$key1} == $key2)) {next;} 
      if (exists $known_interactions{$key2} && ($known_interactions{$key2} == $key1)) {next;} 
      if ($key1 < $key2) { print "$key1,$key2\n"; $count++; } 
      else { print "$key2,$key1\n"; $count++; } 
     } 
     if ($count == $interactions) { 
      die "$count\n"; 
     } 
    } 
} 

답변

-1

우선 무엇을 알면 상호 작용이 알려진 파일에서 뉘앙 거리는 (줄 바꿈을 제거하지 않음) 것입니다. 이 해시를 구축 할 것입니다

1111,2222 

: 중복 항목을 얻고있는 이유는 아마도

$known_interactions{1111} = "2222\n"; 

즉 같은 파일을 주어진 것을 의미한다.

map{ 
    chomp; 
    $entrez_genes{$_}++ ; 
}@e_file; 

map { 
    chomp; 
    my @array = sort(split (/,/)); 
    $known_interactions{$array[0]} = $array[1]; 
}@k_file; 

을 또한, 일반적으로, 나는 내 인생을 찾을 : 내 생각 엔 (실제 입력 파일없이 확신 할 수 없다)이 루프 작업을 확인해야한다는 것입니다 상호 작용하는 쌍 (생물 정보학의 기쁨 :)을 분류하면 더 쉽습니다. 그렇게하면 111,222와 222,111이 동일한 방식으로 처리되며 코드에서와 같이 여러 개의 if 문을 피할 수 있습니다.

당신의 다음 루프는 (이럴 인 더 읽기) 다음과 같습니다

my @genes=keys(%entrez_genes); 
for (my $i=0; $i<=$#genes;$i++) { 
    for (my $k=$n; $k<=$#genes;$k++) { 
    next if $genes[$n] == $genes[$k]; 
    my @pp=sort($genes[$n],$genes[$k]); 
    next unless exists $known_interactions{$pp[0]}; 
    next if $known_interactions{$pp[0]} == $pp[1]; 
    print "$pp[0], $pp[1]\n"; 
    $count++; 
    die "$count\n" if $count == $interactions; 
    } 
} 
+1

하지 않았다, 두 파일의 데이터는 efffectively's의와 chomped한다/\ s + \ z //'. void 문맥에서'map'을 사용하면 안됩니다 : for가'for'입니다.그리고 C 스타일의'for' 루프는 C에서 거의 필요하지 않습니다 : for my $ i (0 .. $ # genes) {...}'를 사용하거나 배열의 * contents * 내 $ genes_i (@genes) {...}' ' – Borodin

+0

@ 보 로딘 실제로, 나는 고쳐 주었고 \ z는 눈치 채지 못했다. for 루프는 반복을 피하기 위해 필요합니다. 나는 바보 였고 $ k = $ n 대신 $ k = 0을 썼다. 그리고 나는 상호 작용하는 쌍을 분류하여 고유 한 이름을 얻는 것에 대한 나의 입장을 고집합니다. – terdon

+0

@Borodin 나는 여기에서 좀 새로운 사람이다. 나는 당신을 PM 할 수있는 방법이있어, 나는 OP의 질문을 훔치지 않는다? 어쩌면 당신은 내가 무효 맥락에서지도를 사용하는 곳을 설명 할 수있을 것입니다. 당신의 프로파일을 보았을 때, 나는 그것을 얻지 못한다는 것을 의심하지 않습니다. – terdon

0

난 당신의 코드를 잘못 아무것도 볼 수 있습니다. 쉼표 나 줄 끝 부분에 데이터에 공백이 있는지 궁금합니다. 당신이 단지의 존재를 확인할 수 있도록, 해시 키와 한 쌍의 모두 요소를 유지 나을 것,

my @e_file = map /\d+/g, <IN>; 

또한 예를 들어, 그냥 숫자 필드를 추출하는 안전 할 것 요소. 낮은 숫자가 항상 처음이면 두 번 조회 할 필요가 없습니다.

이 예제가 유용 할 것입니다. 그것은 당신의 요구 사항의 무작위 선택 부분을 해결하지 않지만, 그 자신의 코드에 아니었고 즉각적인 문제를 질문에서

use strict; 
use warnings; 

@ARGV = qw/ entrez_genes.txt known_interactions.txt 9 /; 

if (@ARGV != 3) { 
    die "Usage: generate_random_pairs.pl <entrez_genes> <known_interactions> <number_of_interactions>\n"; 
} 

my ($e_file, $k_file, $interactions) = @ARGV; 

open my $fh, '<', $e_file or die "Error!! Cannot open $e_file: $!"; 
my @e_file = sort { $a <=> $b } map /\d+/g, <$fh>; 

open $fh, '<', $k_file or die "Error!! Cannot open $k_file: $!"; 
my %known_interactions; 
while (<$fh>) { 
    my $pair = join ',', sort { $a <=> $b } /\d+/g; 
    $known_interactions{$pair}++; 
} 

close $fh; 

my $count = 0; 
PAIR: 
for my $i (0 .. $#e_file-1) { 
    for my $j ($i+1 .. $#e_file) { 
    my $pair = join ',', @e_file[$i, $j]; 
    unless ($known_interactions{$pair}) { 
     print $pair, "\n"; 
     last PAIR if ++$count >= $interactions; 
    } 
    } 
} 

print "\nTotal of $count interactions\n";