如何将此表格格式的输出转换为Perl?
我有这样的输出数据:如何将此表格格式的输出转换为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
是不是这个想法。
此代码有效。它会在碎片编号改变时换行。它假定数据的顺序总是与标题的顺序一致。
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
看起来您只是在打印语句中缺少回车符。例如,
print $1."\t".$4."\n";
也许吧,但是,结果现在打印在一列中,我需要在他们的resp中打印值(或在其各自的RNA中)。 –
啊,我明白了。您必须在“群组”发生变化时触发从10 - > 11等等。这个触发器将让你打印“组”,并返回一个回车符。 您确定数据文件中的行顺序始终与您的标题顺序相同吗? –
顺序可以改变,在这种情况下,顺序是第1列,但它可以通过预先的“sort -n”命令来改变bash命令......任何其他想法? –
事情是这样的:
print $1."\t".$4;
print "\n" if ($2 eq "snRNA");
休息时,你得到的模式 “snRNA的” 行;
这一个不关心什么顺序文件中,并从该数据报头。策略是将数据累积到结构中,然后在检查完所有数据后立即输出所有内容。如果你真的有(真的)大文件,你可能会吃掉内存。
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
下面是号令列由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
优秀的成绩!非常感谢!我是perl begginer,但我很兴奋。谢谢。 –
请注意,但输入文件的顺序必须与标题顺序相匹配。经过仔细观察,上述输出结果中有snoRNA和snRNA列交换。一个更好的脚本会从数据文件中提取标题,而不关心它的顺序。 –
由Wall,Christiansen和Schwartz编写的O'Reilly编程Perl书仍然是最好的恕我直言。 –