2012-08-14 32 views
0

給定一組基因和現有的一對基因,我想生成一對尚未存在的新基因。從數字列表中生成隨機對,確保生成的隨機對不存在

的基因文件格式如下:

123  
134 
23455 
3242 
3423 
... 
... 

的基因對文件的格式如下:

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

但我仍然得到known_interactions和new_pairs之間幾乎沒有共同之處。我不確定錯誤在哪裏。

對於參數,
perl的generate_random_pairs.pl entrez_genes_file known_interactions_file 250000
我的15880.一個共同的元素個數250000告訴我要多少隨機對程序產生。

#! 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與單曲chomped/\ S + \ž//'。你不應該在void上下文中使用'map':這就是'for'的用途。而C風格的'for'循環在C:use'for $ i(0.. $#基因){...}'或更好的情況下很少需要在數組的*內容*中使用'for我的$基因_i(@基因){...}' ' – Borodin 2012-08-14 02:10:30

+0

@Borodin事實上,我站在糾正,沒有注意到\ z。然而for循環需要避免重複。我只是一個白癡,寫了$ k = 0而不是$ k = $ n。我堅持我的意見,就是要對互動對進行排序,以獲得獨特的名稱。 – terdon 2012-08-14 02:28:06

+0

@Borodin我在這裏有點新,有沒有辦法可以PM你,所以我不偷OP的問題?如果你有時間,也許你可以解釋我在無效環境中使用的地圖。看到你的個人資料,我不懷疑它只是不明白:) – terdon 2012-08-14 02:31:59

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";