2012-08-14 37 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";