Perl输出的列数太多

时间:2015-02-13 15:12:35

标签: perl match lookup

我有一张相关标记结果表和一个疾病标记表。两个文件都有标题。

这是相关标记表的样子:

  snps_BCG24 gene_BCG24 statistic_BCG24 pvalue_BCG24    FDR_BCG24 beta_BCG24                 pair SharedOrUnique_BCG24 PercentileRank_BCG24 chr       cM   hg19pos    Diseasegene
rs11203184  C21orf128       -9.425704 4.008530e-12 2.501741e-05 -0.9199033 rs11203184_C21orf128      SharedSignalMO7         1.484874e-06  21  63.4452  43526430 notDiseasegene
rs11203184      C2CD2        2.290434 2.684575e-02 8.559484e-01  0.3114964     rs11203184_C2CD2    UniqueSignalBCG24         2.906046e-01  21  63.4452  43526430 notDiseasegene

这就是疾病标记表的样子:

Chr  hg19Pos  hg18Pos       rsID           SNPname               hg19UCSC               hg18UCSC startLoc   endLoc
1  1247494  1237357    rs12103  var_chr1_1247494   chr1:1247494-1247494   chr1:1237357-1237357  1147494  1347494
1  2502780  2492640  rs6667605  var_chr1_2502780   chr1:2502780-2502780   

如果相关标记和疾病标记位于同一染色体上(分别是相关的第9列= =疾病列0),那么我想检查我的相关标记的位置(相关表中的第11列)是否在疾病标志物的起始和终止位置(疾病表中的第7列和第8列)。

如果我的相关标记位于该距离内,我想标记相关标记"inLocus",否则请留空。结果输出将是具有两个制表符分隔列的文件:1)每个关联标记的名称与关联标记表的相同顺序2)inLocus或相关标记表中每个标记的空白状态。

我为此编写了一个perl脚本,但它不输出两列(一列用于关联的标记名称,一列用于基因座状态),而是输出一列,其中包含标记名称和"inLocus"的不同列数。 part - 并不总是相同的列数。我不知道哪个标记确实是"inLocus",因为每个输出列有时会有不同的状态。我需要在代码中更改哪些内容,以便列表中的每个标记都获得明确的inLocus标签?将空白更改为打印"notLocus"会有所作为吗?这是我的代码:

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

my $data_file1="/Users/Me/AssociatedMarkers.txt";
my $data_file2="/Users/Me/DiseaseMarkers.txt";
open(Main, $data_file1) || die("Could not open file!");

my $Line = 0;
my $Line1 = 0;
my @main = 0;
my @loci = 0;

#Generate output files
open(Result, ">AssociatedMarkersInLocus.txt");
 print Result "SNP\tinLocus?\n";
foreach $Line (<Main>) {
    #remove new line character
    open(DiseaseMarkers, $data_file2) || die("Could not open file!");
    $Line =~ s/[\n\r]//g;
    @main = split(/\t/,$Line);
    print Result "@main[0]";
    foreach $Line1 (< DiseaseMarkers >) {
        $Line1 =~ s/[\n\r]//g;
        @loci = split(/\t/,$Line1);
        if ((@main[9] eq @loci[0])&&(@main[11]>=@loci[7])&&(@main[11]<@loci[8])){
            print Result "\tinlocus";
            close(DiseaseMarkers);
        }
    }
print Result "\n";
}
close(Result);  
#Report completion
print "Program AssociatedMarkers finished. \n";

以下是我得到的结果:

SNP inLocus?                
MarkerNameHeader 
MarkerName1 inLocus     inLocus     inLocus
MarkerName2
MarkerName3             inLocus
MarkerName4 inLocus     inLocus     inLocus
MarkerName5 inLocus

以下是我实际需要的结果格式:

MarkerName1 inLocus
MarkerName2
MarkerName3
MarkerName4 inLocus

或者,如果有人知道如何直接将inLocus信息附加到我现有的AssociatedMarkers文件中,那就更好了!

1 个答案:

答案 0 :(得分:5)

使用您的样本数据进行测试似乎很好..

一点代码审查:

  1. 根据需要声明变量。 Globals可能会让人感到困惑。
  2. 将词法范围的变量用作文件句柄
  3. 使用三个参数
  4. 尝试关闭循环内的文件句柄可能不是你想要做的。我把它移出了几个范围
  5. last LINE会让您摆脱DiseaseMarkers文件
  6. @foo[0]应为$foo[0]
  7. 很高兴看到你没有使用chop / chomp!我修复了你的行结尾正则表达式,使其更加便携..

    无论如何,这应该解决它:

    #!/usr/bin/perl
    use strict;
    use warnings;
    
    my $data_file1 = "/Users/Me/AssociatedMarkers.txt";
    my $data_file2 = "/Users/Me/DiseaseMarkers.txt";
    
    #Open data file and create file handle
    open(my $mainfh, '<', $data_file1) or die "Could not open file! $!";
    
    #define variables and constants
    #Generate output files
    open(my $resultfh, '>', "AssociatedMarkersInLocus.txt") or die "Could not open file for write! $!";
    print $resultfh "SNP\tinLocus?\n";
    
    foreach my $Line (<$mainfh>) {
        #remove new line character
        open(my $dmfh, '<', $data_file2) or die("Could not open file! $!");
        $Line =~ s/[\f\n\r]*$//g;
        my @main = split(/\t/, $Line);
        print $resultfh "$main[0]";
    
        my $has_locus = 0;
    
        LINE: foreach my $Line1 (<$dmfh>) {
            $Line1 =~ s/[\f\n\r]*$//g;
            my @loci = split(/\t/,$Line1);
    
            if (($main[9]  eq $loci[0])
                && ($main[11] >= $loci[7])
                && ($main[11]<$loci[8])) {
    
                $has_locus = 1;
                print $resultfh "\tinlocus";
                last LINE;
            }
        }
    
        if ($has_locus == 0) {
            print $resultfh "\tnolocus";
        }
    
        print $resultfh "\n";
        close($dmfh);
    }
    
    close($resultfh);
    close($mainfh);
    
    #Report completion
    print "Program AssociatedMarkers finished.\n";