Perl:将哈希数组转换为矩阵

时间:2012-01-23 20:54:52

标签: perl r hash matrix

我有一个哈希数组,其中许多都有共享密钥。

我想将其转换为在[R]中进行分析的矩阵,这样每行代表一个哈希值,每个唯一键都是一列,即(空白)或“。”如果散列不包含该特定键,则为“NA”。

目前我正计划在哈希数组中找到每个唯一键,并通过循环遍历每个哈希来构造我的矩阵......但是必须有更好的方法吗?

谢谢!

示例:

my %hash_A = (
  A=> 12,
  B=> 23,
  C=> 'a string'
  );
my %hash_B = (
  B=> 23,
  C=> 'a different string',
  D=> 99
  );

给予:

A,B,C,D
12,23,'a string',NA
NA, 23, 'a different string', 99

3 个答案:

答案 0 :(得分:2)

如果确保每个可能的键都将每个哈希值初始化为“NA”,那么你基本上有一个矩阵,你可以将它打印出来......(当数据不是“NA”时,数据应该被覆盖“)

如果无法初始化它们,那么只需事先跟踪所有可能的键,然后在打印数据结构时循环它们(而不是循环遍历每个单独散列的键)。

my @possibleKeys = keys %possibleKeys;
foreach my $hashref (@arrayOfHashes)
    foreach my $key (@possibleKeys) {
        if(!defined ${$hashref}{$key}) { 
            print "NA "; 
        else { 
            print "$hashref{$key} "; 
        }
    print "\n"; 
    }
}

修改 keys %possibleKeys将为每次调用返回不同排序的数组(请参阅http://perldoc.perl.org/functions/keys.html),因此密钥应存储在数组中以保持顺序。

答案 1 :(得分:1)

这应该将哈希数组转换为2D数组(@output1)。

没有相应输入值的所有输出单元格将填充'NA'。 (如果您不介意将未映射的单元格映射到undef,那么可以更简洁地完成此操作 - 请参阅@output2。)

数组@keys将说明哪个散列键与输出行中的每个索引位置相关。

my @array_of_hashes = ...;

my %keys

for my $hash (@array_of_hashes) {
    @keys{keys %$hash} = ();
}

my @keys = sort keys %keys;

my @output1 = map {
    my $hash = $_;

    [ map { exists $$hash{$_} ? $$hash{$_} : 'NA' } @keys ];
} @array_of_hashes;

my @output2 = map [ @$_{@keys} ] => @array_of_hashes;

答案 2 :(得分:1)

my @a = ( keys %hash_A, keys %hash_B );
my %r;
@r{@a} = @a;
for my $h ( \%r, \%hash_A, \%hash_B ) {
    print join( ', ', map { $$h{$_} ||= 'NA' } sort keys %r ), "\n";
}