0

私はこの出力を持っています:

10dvex2_miRNA_ce.out.data|6361
10dvex2_miRNA_ce.out.data|6361
10dvex2_misc_RNA_ce.out.data|0
10dvex2_rRNA_ce.out.data|239

Perl で次のスクリプトを使用します。

#!/usr/bin/perl

use warnings;
use strict;

open(MYINPUTFILE, $ARGV[0]); # open for input
my @lines = <MYINPUTFILE>; # read file into list
my $count = 0;
print "Frag"."\t"."ncRNA"."\t"."Amount"."\n";

foreach my $lines (@lines){
my $pattern = $lines;
$pattern =~ s/(.*)dvex\d_(.*)_(.*).(out.data)\|(.*)/$1 $2   $3  $5/g;
$count += $5;
print $1."\t".$2.$3."\t".$5."\n";
}
close(MYINPUTFILE);
exit;

この情報を抽出します。

Frag    ncRNA   Amount
10  miRNAce 6361
10  misc_RNAce  0
10  rRNAce  239

しかし、[金額] 列では、これらの数値を合計結果 (6600) で割った値を報告したいと考えています。この場合、次の出力が必要です。

Frag    ncRNA   Amount
10  miRNAce 0.964
10  misc_RNAce  0
10  rRNAce  0.036

私の問題は、ループ内の TOTAL 結果を抽出することです...このデータを正規化します。いくつかのアイデア?

4

2 に答える 2

1

おそらく、次のことが役立つでしょう:

use strict;
use warnings;

my ( %hash, $total, %seen, @array );

while (<>) {
    next if $seen{$_}++;
    /(\d+).+?_([^.]+).+\|(\d+)$/;
    $hash{$1}{$2} = $3;
    $total += $3;
}

print "Frag\tncRNA\tAmount\n";

while ( my ( $key1, $val1 ) = each %hash ) {
    while ( my ( $key2, $val2 ) = each %$val1 ) {
        my $frac = $val2 / $total == 0 ? 0 : sprintf( '%.3f', $val2 / $total );
        push @array, "$key1\t$key2\t$frac\n";
    }
}

print map { $_->[0] }
  sort    { $b->[1] <=> $a->[1] }
  map { [ $_, (split)[2] ] }
  @array;

データセットからの出力:

Frag    ncRNA   Amount
10  miRNA_ce    0.964
10  rRNA_ce 0.036
10  misc_RNA_ce 0

同一の行はスキップされ、必要な要素が各行からキャプチャされます。累計は、後続の計算のために保持されます。目的の出力は、高から低への並べ替えを示しました。これが、各レコードがにpush編集される理由@arrayです。ただし、並べ替えが必要ない場合は、その行を印刷して、のシュワルツ変換を省略できます@array

お役に立てれば!

于 2012-11-06T20:47:20.143 に答える
1

これを行うには、データに対して 2 つのパスが必要です。

#! /usr/bin/env perl

use warnings;
use strict;

print join("\t",qw'Frag ncRNA Amount'),"\n";

my @data;
my $total = 0;

# parse the lines
while( <> ){
  my @elem = /(.+?)(?>dvex)\d_(.+)_([^._]+)[.]out[.]data[|](d+)/;
  next unless @elem;

  # running total
  $total += $elem[-1];

  # combine $2 and $3
  splice @elem, 1, 2, $2.$3; # $elem[1].$elem[2];

  push @data, \@elem;
}

# print them
for( @data ){
  my @copy = @$_;
  $copy[-1] = $copy[-1] / $total;
  $copy[-1] = sprintf('%.3f', $copy[-1]) if $copy[-1];
  print join("\t",@copy),"\n";
}
于 2012-11-06T21:00:36.893 に答える