2012-01-23 72 views
3

我有一個散列數組,其中很多都有共享密鑰。Perl:將哈希數組轉換爲矩陣

我想將其轉換爲[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 
+1

你能證明你的數據結構的一個小例子,所需的輸出? – dgw

+0

我不是一個[PDL](http://pdl.perl.org)用戶,但是這似乎是我認爲這個團隊必須經常做的事情,並且有一個簡單的方法可以做。 – Joe

回答

1

這應該將散列數組轉換爲二維數組(@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

如果你確保每個哈希初始化爲「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
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"; 
}