我有一个基因型矩阵,其中:
我想将此矩阵转换为perl HoH以获得基因型(特定于单个样本及其基因座)。
我的矩阵看起来像:
CDS BC1-III BC1-IV BC10-II
LOC105031928 P1/P2 P1/P2 P1/P2
LOC105031930 NA NA NA
LOC105031931 P1/P1 P1/P1 P1/P1
LOC105031933 P1/P1 P1/P1 P1/P1
LOC105031934 NA NA NA
LOC105031935 P1/P1 P1/P1 P1/P1
LOC105031937 NA NA NA
LOC105031938 P1/P1 P1/P1 P1/P1
作为输出,代码应该给出:
$hash{$sample}{$locus} = P1/P1 #(for locus LOC105031935 in sample BC10-II for example)
这是我尝试解决问题的方法,但我还想弄清楚如何在第一列的每个轨迹中将哈希值分配为此哈希表的第二个键。 @sample_names是三个样本的列表。
open(GENOTYPE, '<', "$matrix_geno") or die ("Cannot open $matrix_geno\n");
my %hash;
while (my $line = <GENOTYPE>)
{
my @columns = split(/\s+/, $line);
@hash{@sample_names} = @columns;
#print Dumper \%hash;
}
任何帮助都将受到严重欢迎。
PS:这个例子只是我数据的一小部分。我实际上正在寻求更通用的解决方案
非常感谢你。
答案 0 :(得分:2)
<强>代码:强>
#!/usr/bin/perl
use strict; use warnings; use Data::Dumper;
my $matrix_geno = 'input.io';
open ( my $GENOTYPE, '<', "$matrix_geno" ) or die ($!);
my $header = <$GENOTYPE>;
chomp($header);
my @headers = split( /\s+/, $header );
my %hash = ();
while ( my $line = <$GENOTYPE> ) {
chomp($line);
my @columns_data = split( /\s+/, $line );
$hash{$columns_data[0]}{$headers[1]} = $columns_data[1];
$hash{$columns_data[0]}{$headers[2]} = $columns_data[2];
$hash{$columns_data[0]}{$headers[3]} = $columns_data[3];
}
print Dumper(\%hash);
close($GENOTYPE);
<强>输出:强>
$VAR1 = {
'LOC105031933' => {
'BC1-III' => 'P1/P1',
'BC10-II' => 'P1/P1',
'BC1-IV' => 'P1/P1'
},
'LOC105031934' => {
'BC1-III' => 'NA',
'BC10-II' => 'NA',
'BC1-IV' => 'NA'
},
'LOC105031938' => {
'BC1-IV' => 'P1/P1',
'BC1-III' => 'P1/P1',
'BC10-II' => 'P1/P1'
},
'LOC105031931' => {
'BC10-II' => 'P1/P1',
'BC1-III' => 'P1/P1',
'BC1-IV' => 'P1/P1'
},
'LOC105031937' => {
'BC1-IV' => 'NA',
'BC10-II' => 'NA',
'BC1-III' => 'NA'
},
'LOC105031935' => {
'BC1-III' => 'P1/P1',
'BC10-II' => 'P1/P1',
'BC1-IV' => 'P1/P1'
},
'LOC105031928' => {
'BC1-IV' => 'P1/P2',
'BC10-II' => 'P1/P2',
'BC1-III' => 'P1/P2'
},
'LOC105031930' => {
'BC1-III' => 'NA',
'BC10-II' => 'NA',
'BC1-IV' => 'NA'
}
};
这是您想要的输出吗?
希望这会有所帮助,请根据您的需要进行更改。
答案 1 :(得分:2)
这似乎做你想要的。我是为了简单而从DATA
阅读。
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
use Data::Dumper;
# Read headers
chomp(my $headers = <DATA>);
my @samples = split /\s+/, $headers;
# Remove 'CDS'
shift @samples;
my %genotype;
while (<DATA>) {
chomp;
my ($locus, @genotypes) = split;
for my $x (0 .. $#samples) {
$genotype{$samples[$x]}{$locus} = $genotypes[$x];
}
}
# Display the data structure
say Dumper \%genotype;
# Simple test
say $genotype{'BC10-II'}{LOC105031935};
__DATA__
CDS BC1-III BC1-IV BC10-II
LOC105031928 P1/P2 P1/P2 P1/P2
LOC105031930 NA NA NA
LOC105031931 P1/P1 P1/P1 P1/P1
LOC105031933 P1/P1 P1/P1 P1/P1
LOC105031934 NA NA NA
LOC105031935 P1/P1 P1/P1 P1/P1
LOC105031937 NA NA NA
LOC105031938 P1/P1 P1/P1 P1/P1
输出如下:
$VAR1 = {
'BC10-II' => {
'LOC105031931' => 'P1/P1',
'LOC105031935' => 'P1/P1',
'LOC105031930' => 'NA',
'LOC105031928' => 'P1/P2',
'LOC105031937' => 'NA',
'LOC105031938' => 'P1/P1',
'LOC105031933' => 'P1/P1',
'LOC105031934' => 'NA'
},
'BC1-IV' => {
'LOC105031934' => 'NA',
'LOC105031933' => 'P1/P1',
'LOC105031938' => 'P1/P1',
'LOC105031937' => 'NA',
'LOC105031928' => 'P1/P2',
'LOC105031930' => 'NA',
'LOC105031935' => 'P1/P1',
'LOC105031931' => 'P1/P1'
},
'BC1-III' => {
'LOC105031931' => 'P1/P1',
'LOC105031935' => 'P1/P1',
'LOC105031930' => 'NA',
'LOC105031928' => 'P1/P2',
'LOC105031937' => 'NA',
'LOC105031938' => 'P1/P1',
'LOC105031933' => 'P1/P1',
'LOC105031934' => 'NA'
}
};
P1/P1