2017-04-06 7 views
1

のマトリックスを作成します。私は、各サンプルが結果水を与える頻度を数えるハッシュを作成し私はこのようになります冗長リストを入力していた冗長リストから

Sample1.14 Water 
Sample2.45 Air 
Sample1.16 Dirt 
Sample1.14 Water 
Sample2.45 Air 
Sample1.16 Dirt 
Sample1.14 Water 
Sample2.45 Air 
Sample1.16 Dirt 
Sample1.16 Dirt 
Sample1.14 Dirt 
Sample2.45 Air 
Sample1.16 Air 

を、空気、土が(この点に注意してくださいです単なるデータ例ですが、構造は同じです)。

use warnings; 
    use strict; 
    my $inPut = "ExampleSample"; 
    open(READ,$inPut) || die "Coult not read $inPut: $!"; 

    my %sampleHash; 

    while (<READ>) { 

     chomp; 
     my @temp = split("\t",$_); 

     my $sample = $temp[0]; 

     my $type = $temp[1]; 

     $sampleHash{$type}{$sample} += 1; 

    } 

これは意図したとおりに動作し、出力として得られます。

$VAR1 = { 
      'Dirt' => { 
         'Sample1.16' => 4, 
         'Sample1.14' => 1 
        }, 
      'Air' => { 
        'Sample1.16' => 1, 
        'Sample2.45' => 4 
        }, 
      'Water' => { 
         'Sample1.14' => 3 
        } 
     }; 

これは私がやや失われた午前行列にこのデータを入れたいと思い、さらに下流のもののための静かな不正なデータ構造であるので、で。

所望の出力またはこの例の転置、本当に問題ではない:

Sample1.14 Sample2.45 Sample1.16 
Air  0   4   1 
Dirt 4   0   4 
Water 3   0   0 

私は本当にすべてのヘルプは非常に高く評価されるだろう、ここで立ち往生しています!ありがとう。

+1

例の変数名が間違っています。 – simbabque

+0

お手伝いするために、私たちはあなたの下流のものが必要とするものを理解する必要があります。それがわからない場合は、後でデータを使って何をするつもりか教えてください。あなたが現在持っている構造はとても典型的です。データを見ると、私は同じことをしているだろう。タイプごとにグループ化し、サンプルを数えます。これは、最初のキーが行で、2番目のキーが列であることを示した表に対応します。 – simbabque

+0

ヘッドアップありがとう。ダウンストリーム私は、どのサンプルがどのタイプで最も頻繁に出現するかを見るためにマトリックス構造を持つ出力ファイルを作成したいが、グループ分けが冗長であるため、データをR読み取り可能なフォーマットにする方法はあまりよく分からない。 – chrys

答えて

1

Perlで独自のリストを作成する最も簡単な方法は、ダミーの値を持つハッシュキーなどの要素を使用することです。ハッシュを塗りつぶした後、keysで値のユニークなリストを得ることができます。

my %samples; 
$samples{"some value"} = 1; 
$samples{"some other value"} = 1; 
$samples{"some value"} = 1; 
my @samples = sort keys %samples; 

あなたはPerlがawkように振る舞うようにしたい場合は、単一のスペース引数を指定してsplit関数を使用することができます。また、分割結果を2つの変数に代入したい場合は、Perlのリスト表記を使用することができます。

my ($a, $b) = split ' '; 

複雑な部分はテーブルを構築することです。これはforループまたはmapによって実行できます。 forループを使用すると読みやすくなりますが、mapではよりコンパクトな表記が可能になります。

以下は、配列参照(角括弧)を作成し、$tという値を前に付けたmap式の戻りリストで配列を塗りつぶします。 map式は、コードとリストを1つずつ取り出し、リストの各要素のコードを実行します。現在のリスト要素の値は、変数$_にあります。

[ $t, map { $sampleHash{$t}{$_} or '0' } @samples ] 

ネストmap表現する場合は、内部$_影外側ので、インナーmapからアクセスするために、外側$_に名前を与える必要があります。

Perlでテーブルをフォーマットする基本的な方法は、Perlのレポート機能perlformを使用することです。そのためには、交互に並んだ線のリストを定義する必要があります。最初はパターン線、次に値線です。あなたはすべて一緒に置く場合

はあなたの例では、この

 
     Sample1.14 Sample1.16 Sample2.45 
Air   0   1   4 
Dirt   1   4   0 
Water   3   0   0 

注意を出力し、この

#! /usr/bin/perl 
use strict; 
use warnings; 

my %sampleHash; 
my %samples; 
my %types; 

while (<DATA>) 
{ 
    chomp; 
    my ($sample, $type) = split ' '; 
    $sampleHash{$type}{$sample} += 1; 
    $samples{$sample} = 1; 
    $types{$type} = 1; 
} 

my @samples = sort keys %samples; 
my @types = sort keys %types; 

my @table = 
    (['', @samples], 
    map { my $t=$_; [ $t, map { $sampleHash{$t}{$_} or '0' } @samples ] } @types); 

my $row; 
format = 
@<<<<<< @|||||||||| @|||||||||| @|||||||||| 
@$row 
. 
for $row (@table) { write; } 

__DATA__ 
Sample1.14 Water 
Sample2.45 Air 
Sample1.16 Dirt 
Sample1.14 Water 
Sample2.45 Air 
Sample1.16 Dirt 
Sample1.14 Water 
Sample2.45 Air 
Sample1.16 Dirt 
Sample1.16 Dirt 
Sample1.14 Dirt 
Sample2.45 Air 
Sample1.16 Air 

を次のようになります。あなたの所望の出力は、あなたの入力と一致していません。

ファイルを読み取るには、コードをopenで保存する必要があります。私はセクションを使用して、MCVEを得るために例を単純化しました。

2

ハッシュのハッシュを配列の配列に "munge"し、Acme::Tools :: pivot()またはData::Pivot :: pivot()に入力できます。このように:

use Acme::Tools; 
my $data={ 
    'Dirt' => { 
     'Sample1.16' => 4, 
     'Sample1.14' => 1 
    }, 
    'Air' => { 
     'Sample1.16' => 1, 
     'Sample2.45' => 4 
    }, 
    'Water' => { 
     'Sample1.14' => 3 
    } 
}; 
my @sample=uniq(sort map keys(%$_), values %$data); 
my @element=sort keys %$data; 
my $data2=[ map { my $x=$_; map [$x,$_,$$data{$x}{$_}||' 0'], @sample } @element ]; 
print tablestring([Acme::Tools::pivot($data2,"Element")]); 

出力:

Element Sample1.14 Sample1.16 Sample2.45 
------- ---------- ---------- ---------- 
Air    0   1   4 
Dirt    1   4   0 
Water   3   0   0