Perl 输出太多列

Perl outputs too many columns

我有一个 table 相关标记结果和一个 table 疾病标记结果。两个文件都有 headers。

这是关联标记 table 的样子:

  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

这是疾病标记 table 的样子:

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列) 41=]) 落在疾病标记的开始和结束位置内(疾病 table 中的第 7 列和第 8 列)。

如果我的关联标记在该距离内,我想标记该关联标记 "inLocus",否则留空。结果输出将是一个包含两个 tab-delimited 列的文件:1) 每个关联标记的名称与关联标记的顺序相同 table 2) inLocus 或每个标记的空白状态在相关标记 table 中。

我为此编写了一个 perl 脚本,但不是输出两列(一列用于相关标记名称,一列用于基因座状态),而是输出一列标记名称和不同数量的列 "inLocus" 部分——并不总是相同的列数。我不知道哪个标记是真正的 "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. 根据需要声明变量。全局变量可能会让人感到困惑。
  2. 使用词法范围变量作为文件句柄
  3. 使用三个参数打开
  4. 尝试在循环内关闭文件句柄可能不是您想要做的。我把它移出了几个范围
  5. last LINE 将使您脱离 DiseaseMarkers 文件
  6. @foo[0] 应该是 $foo[0]

很高兴看到您没有使用 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";