Text-Processing
使用 awk/sed/perl 組織三維數據
我有這個文件(一個稀疏矩陣):
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 ""; } }
請注意,我已明確包含範例輸出中的所有行和列。如果數據實際上包含所有行和列,而您的範例數據不包含這些行和列,則這不是必需的。