awk/sed/perl을 사용하여 3D 데이터 구성

awk/sed/perl을 사용하여 3D 데이터 구성

다음 파일이 있습니다(희소 행렬).

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)에 대한 비슷한 질문을 찾았지만 익숙하지 않습니다.

답변1

펄에서는:

#!/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";
}

답변2

존재하다 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 "";
    }
}

예제 출력의 모든 행과 열을 명시적으로 포함했습니다. 데이터에 실제로 모든 행과 열이 포함되어 있으면 이 작업을 수행할 필요가 없습니다(예제 데이터에서는 그렇지 않음).

관련 정보