0

我遇到了一个小故障。我有 2 个文件,如下所示:

文件 1

chr10   179423  181499  181423  2076    +   NM_001202464    ZMYND11
chr10   693887  696118  695887  2231    +   NR_027151   C10orf108
chr10   694016  696382  696016  2366    +   NR_027152   C10orf108
chr10   1032348 1034467 1034348 2119    +   NM_012341   GTPBP4
chr10   1203707 1205930 1205707 2223    +   NR_015376   LINC00200

文件2

chr10   176225
chr10   180990
chr10   181315
chr10   181529
chr10   181695
chr10   182183
chr10   686673
chr10   686699
chr10   688273
chr10   695323
chr10   698323
chr10   722737
chr10   906075
chr10   908409
chr10   928052
chr10   950429
chr10   989722
chr10   1006348
chr10   1010731
chr10   1020229
chr10   1034526
chr10   1064089
chr10   1103000
chr10   1103198
chr10   1103267
chr10   1114980
chr10   1135327
chr10   1150625
chr10   1193412
chr10   1193677
chr10   1199817
chr10   1212181
chr10   1212310
chr10   1216875
chr10   1218919
chr10   1226134
chr10   1226254

需要什么

逐行,对于每个4th elementfromFile1打印出其中的File2>= 2nd element from file1 & <= (4th element from file1+2000)

例如, in File1, in 的第 4 个元素row1181423。从File2中,>= 2nd element from file1 (179423)<= 4th element from file1+2000(183423)的值为 18090,181315,181529,181695,182183。

如果没有找到值,NA则应打印。

期望的输出

一个制表符分隔的文件,如下所示:

chr10   179423  181423  183423  NM_001202464    ZMYND11     180990
                                                            181315
                                                            181529
                                                            181695
                                                            182183
chr10   693887  695887  697887  NR_027151   C10orf108       695323
chr10   694016  696016  698016  NR_027152   C10orf108       695323
chr10   1032348 1034348 1036348 NM_012341   GTPBP4          1034526
chr10   1203707 1205707 1207707 NR_015376   LINC00200       NA  

我的代码

我完全不知道如何去做。最初,有人告诉我,我只需要找到那些file2介于2nd4th元素之间的值file1。为此,我使用哈希编写了以下代码,虽然可以工作,但并没有完成完整的工作。(循环中的&&部分if没有做我认为应该做的事情,所以所有更大的值都被打印出来了)

现在这段代码完全没用了:/我束手无策,因为我不知道是否在进入 Perl 编程的 3 个月内,我应该能够编写狡猾的程序。

use 5.014;
use warnings;

#Assign filenames
my $file1 = 'file1.txt' || die $!; #File with TSS coordinates
my $file2 = 'file2.txt' || die $!; #File with G4 coordinates

#Open files
open my $fh1, '<' , $file1 || die $!;
open my $fh2, '<' , $file2 || die $!;

#Open output
open OUT, ">G4_coordinates_promoters$file1.out" || die $!;

#Read files
while (<$fh1>) {
    chomp;
    my %data1; #Hash for TSS
    my ($key1, $val1) = (split) [1,3];
    $data1{$key1} = $val1;
    while (<$fh2>) {
        chomp ;
        my %data2; #Hash for G4 coordinates
        my ($key2, $val2) = (split) [1,2];
        $data2{$key2} = $val2;

        #Compare hashes
        if ( ($key2 > $key1) && 
             ($key2 << $data1{$key1})){ #Here the code after && is NOT working
            say OUT $key2
        }
    }
} 

谢谢你解决我的问题。如果能找到一些直接的方法来解决这个问题,我将不胜感激。

4

1 回答 1

3

该程序似乎可以满足您的需求。

输出以制表符分隔格式写入 - 与您的输入数据相同 - 因此连续行具有正确数量的制表符,但与初始行没有物理对齐。如果您想要不同的东西,请说出来。

中的所有值file2都被拉入数组@file2并从那里处理。代码假定这些值已经排序。

while (<$fh>) {
  chomp;
  my @fields = split /\t/;

  my $min = $fields[1];
  my $max = $fields[3] + 2000;

  my @values;
  for my $val (@file2) {
    last if $val > $max;
    push @values, $val if $val >= $min;
  }
  push @values, 'NA' unless @values;

  for my $val (@values) {
    print join("\t", @fields, $val), "\n";
    $_ = '' for @fields;
  }
}

输出

chr10 179423  181499  181423  2076  + NM_001202464  ZMYND11 180990
                181315
                181529
                181695
                182183
chr10 693887  696118  695887  2231  + NR_027151 C10orf108 695323
chr10 694016  696382  696016  2366  + NR_027152 C10orf108 695323
chr10 1032348 1034467 1034348 2119  + NM_012341 GTPBP4  1034526
chr10 1203707 1205930 1205707 2223  + NR_015376 LINC00200 NA
于 2013-03-07T11:09:31.030 回答