将二维矩阵转换为perl哈希

时间:2017-06-13 12:37:44

标签: perl matrix hash

我有一个基因型矩阵,其中:

  • 行代表locus
  • 列代表样本
  • 如果未确定基因型,每个值代表一个基因型,可以是P1 / P1,P2 / P2,P1 / P2或NA。

我想将此矩阵转换为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:这个例子只是我数据的一小部分。我实际上正在寻求更通用的解决方案

非常感谢你。

2 个答案:

答案 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