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 文件中,那就更好了!
用你的样本数据测试似乎不错..
一点代码审查:
- 根据需要声明变量。全局变量可能会让人感到困惑。
- 使用词法范围变量作为文件句柄
- 使用三个参数打开
- 尝试在循环内关闭文件句柄可能不是您想要做的。我把它移出了几个范围
last LINE
将使您脱离 DiseaseMarkers 文件
@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";
我有一个 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 文件中,那就更好了!
用你的样本数据测试似乎不错..
一点代码审查:
- 根据需要声明变量。全局变量可能会让人感到困惑。
- 使用词法范围变量作为文件句柄
- 使用三个参数打开
- 尝试在循环内关闭文件句柄可能不是您想要做的。我把它移出了几个范围
last LINE
将使您脱离 DiseaseMarkers 文件@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";