Text-Processing

使用 awk/sed/perl 組織三維數據

  • May 26, 2016

我有這個文件(一個稀疏矩陣):

PC.354 OTU1 6
PC.354 OTU2 1
PC.356 OTU0 4
PC.356 OTU2 7
PC.356 OTU3 3

我想要這樣的輸出(密集矩陣-經典 .biom 表):

OTU_ID PC.354  PC.355  PC.356
OTU0   0   0   4
OTU1   6   0   0
OTU2   1   0   7
OTU3   0   0   3

如何使用 awk/perl/sed 做到這一點?我發現了一個關於 R 包(xtabs/tidyr)的類似問題,但我不習慣。

在 perl 中:

#!/usr/bin/perl

my (%hotu, %hpc)=();
while(<>){
 my($pc,$otu,$v)=split;
 $hpc{$pc}=1;
 ($hotu{$otu} or $hotu{$otu}={})->{$pc}+=$v;
}
#headers
my @apc = sort keys %hpc;
print join ("\t", 'OTU_ID', @apc) . "\n";
#values
foreach my $otu (sort keys %hotu) {
 print join ("\t", $otu, map {$_=0 unless defined; $_} @{$hotu{$otu}}{@apc}) . "\n";
}

awk

{ data[$2, $1] = $3; }
END {
   split("OTU0 OTU1 OTU2 OTU3", rows);
   split("OTU_ID PC.354 PC.355 PC.356", cols);
   for (i = 1; i <= 4; i++) {
       printf("%10s", cols[i]);
   }
   print "";
   for (i = 1; i <= 4; i++) {
       printf("%-10s", rows[i]);
       for (j = 2; j <= 4; j++) {
           item = data[rows[i], cols[j]];
           if (!item) { item = "0" };
           printf("%10s", item);
       }
       print "";
   }
}

請注意,我已明確包含範例輸出中的所有行和列。如果數據實際上包含所有行和列,而您的範例數據不包含這些行和列,則這不是必需的。

引用自:https://unix.stackexchange.com/questions/285493