2012-11-01 92 views
2

我有這樣的輸出數據:如何將此表格格式的輸出轉換爲Perl?

10dvex1_miRNA_ce.out.data|3331 
10dvex1_misc_RNA_ce.out.data|0 
10dvex1_rRNA_ce.out.data|60 
10dvex1_snoRNA_ce.out.data|895 
10dvex1_snRNA_ce.out.data|2127 
11dvex1_miRNA_ce.out.data|3367 
11dvex1_misc_RNA_ce.out.data|0 
11dvex1_rRNA_ce.out.data|54 
11dvex1_snoRNA_ce.out.data|839 
11dvex1_snRNA_ce.out.data|1770 
12dvex1_miRNA_ce.out.data|3321 
12dvex1_misc_RNA_ce.out.data|0 
12dvex1_rRNA_ce.out.data|50 
12dvex1_snoRNA_ce.out.data|854 
12dvex1_snRNA_ce.out.data|1821 

我想這個輸出轉換這種格式,像如表:

`Fragment \t miRNA \t misc_RNA \t rRNA \t snRNA \t snoRNA` 
10 \t 3331 \t 0 \t 60 \t 2127 \ 895 \n 
11 \t 3367 \t 0 \t 54 \t 1770 \t 839 \n 
12 \t 3321 \t 0 \t 50 \t 1821 \t 854 \n 

我需要使用此表作爲輸入R.一些想法?我試圖用這個腳本perl的,但結果地圖無法很好:

#!/usr/bin/perl 

use warnings; 
use strict; 

open(MYINPUTFILE, $ARGV[0]); # open for input 
my @lines = <MYINPUTFILE>; # read file into list 
print "Frag"."\t"."miRNA"."\t"."misc_RNA"."\t"."rRNA"."\t"."snRNA"."\t"."snoRNA"."\n"; 
foreach my $lines (@lines){ 
    my $pattern = $lines; 
    $pattern =~ s/(.*)dvex\d_(.*)_(.*)\|(.*)/$1 $2 $4/g; 
    print $1."\t".$4; 
} 
close(MYINPUTFILE); 
exit; 

而結果:

Frag miRNA misc_RNA rRNA snRNA snoRNA 
10 333110 010 6010 89510 212711 336711 011 5411 83911 177012 332112 012 5012 

是不是這個想法。

回答

1

此代碼有效。它會在碎片編號改變時換行。它假定數據的順序總是與標題的順序一致。

open(MYINPUTFILE, $ARGV[0]); # open for input 
my @lines = <MYINPUTFILE>; # read file into list 
print "Frag"."\t"."miRNA"."\t"."misc_RNA"."\t"."rRNA"."\t"."snRNA"."\t"."snoRNA"; 
my $frag = ''; 
foreach my $line (@lines){ 
    if ($line =~ /^(\d+)dvex.*\|(\d+)/) { 
     my $fr = $1; 
     if ($fr ne $frag) { 
      print "\n$fr"; 
      $frag = $fr; 
     } 
     print "\t".$2; 
    } 
} 
print "\n"; 
close(MYINPUTFILE); 
exit; 

輸出的樣子:

Frag miRNA misc_RNA  rRNA snRNA snoRNA 
10  3331 0  60  895  2127 
11  3367 0  54  839  1770 
12  3321 0  50  854  1821 
+0

優秀的成績!非常感謝!我是perl begginer,但我很興奮。謝謝。 –

+0

請注意,但輸入文件的順序必須與標題順序相匹配。經過仔細觀察,上述輸出結果中有snoRNA和snRNA列交換。一個更好的腳本會從數據文件中提取標題,而不關心它的順序。 –

+0

由Wall,Christiansen和Schwartz編寫的O'Reilly編程Perl書仍然是最好的恕我直言。 –

1

看起來您只是在打印語句中缺少回車符。例如,

print $1."\t".$4."\n"; 
+0

也許吧,但是,結果現在打印在一列中,我需要在他們的resp中打印值(或在其各自的RNA中)。 –

+0

啊,我明白了。您必須在「羣組」發生變化時觸發從10 - > 11等等。這個觸發器將讓你打印「組」,並返回一個回車符。 您確定數據文件中的行順序始終與您的標題順序相同嗎? –

+0

順序可以改變,在這種情況下,順序是第1列,但它可以通過預先的「sort -n」命令來改變bash命令......任何其他想法? –

1

事情是這樣的:

print $1."\t".$4; 
print "\n" if ($2 eq "snRNA"); 

休息時,你得到的模式 「snRNA的」 行;

0

這一個不關心什麼順序文件中,並從該數據報頭。策略是將數據累積到結構中,然後在檢查完所有數據後立即輸出所有內容。如果你真的有(真的)大文件,你可能會吃掉內存。

open(MYINPUTFILE, $ARGV[0]); # open for input 
my @lines = <MYINPUTFILE>; # read file into list 
close(MYINPUTFILE); 

## parse the data 
my $types_found = {}; 
my $data = {}; 
foreach my $line (@lines){ 
    if ($line =~ /^(\d+)dvex\d+_(.+)_ce\.out\.data\|(\d+)/) { 
     $types_found->{$2} = ''; 
     $data->{$1}{$2} = $3; 
    } 
} 

## print the header 
my @types = sort keys %$types_found; 
print "Frag"; 
foreach my $type (@types) { 
    print "\t" . $type; 
} 
print "\n"; 

## print the rows 
foreach my $frag (sort keys %$data) { 
    print $frag; 
    foreach my $type (@types) { 
     print "\t" . $data->{$frag}{$type}; 
    } 
    print "\n"; 
} 

輸出:

Frag miRNA misc_RNA  rRNA snRNA snoRNA 
10  3331 0  60  2127 895 
11  3367 0  54  1770 839 
12  3321 0  50  1821 854 
0

下面是號令列由OP的要求另一種選擇:

use strict; 
use warnings; 

my %hash; 
my @header = qw (Frag miRNA misc_RNA rRNA snRNA snoRNA); 

/(\d+).+?_(.+)_ce.+\|(.+)/ and $hash{$1}{$2} = $3 for <>; 

print +(join "\t", @header) . "\n"; 

for my $key (sort { $a <=> $b } keys %hash) { 
    my @line; 
    push @line, $hash{$key}{ $header[$_] } for 1 .. $#header; 
    print +(join "\t", $key, @line) . "\n"; 
} 

輸出:

Frag miRNA misc_RNA rRNA snRNA snoRNA 
10 3331 0 60 2127 895 
11 3367 0 54 1770 839 
12 3321 0 50 1821 854 
相關問題