데이터 구조

데이터 구조

다음 형식의 출력이 있습니다.

count  id     type
588    10 |    3
 10    12 |    3
883    14 |    3
 98    17 |    3
 17    18 |    1
77598    18 |    3
10000    21 |    3
17892     2 |    3
20000    23 |    3
 63    27 |    3
  6     3 |    3
 2446    35 |    3
 14    4 |    3
 15     4 |    1
253     4 |    2
19857     4 |    3
 1000     5 |    3
...

이것은 매우 지저분하므로 프로젝트 관리자에게 보내 스프레드시트를 엉망으로 만들 수 있도록 CSV 파일로 정리해야 합니다.

문제의 핵심은 다음과 같습니다. 필요한 출력은 다음과 같습니다.

id, sum_of_type_1, sum_of_type_2, sum_of_type_3

ID "4"는 예입니다.

14    4 |    3
 15     4 |    1
253     4 |    2
19857     4 |    3

이것은 아마도 다음과 같습니다:

4,15,253,19871

불행하게도 나는 이런 종류의 일에 대해 서툴러서 모든 행을 정리하고 CSV로 변환했지만 행의 중복을 제거하고 그룹화할 수는 없습니다. 이제 나는 이것을 가지고 있습니다 :

awk 'BEGIN{OFS=",";} {split($line, part, " "); print part[1],part[2],part[4]}' | awk '{ gsub (" ", "", $0); print}'

하지만 해야 할 일은 정크 문자를 정리하고 해당 줄을 다시 인쇄하는 것뿐입니다.

위 출력에 행을 적용하는 가장 좋은 방법은 무엇입니까?

답변1

한 가지 방법은 모든 것을 해시에 넣는 것입니다.

# put values into a hash based on the id and tag
awk 'NR>1{n[$2","$4]+=$1}
END{
    # merge the same ids on the one line
    for(i in n){
        id=i;
        sub(/,.*/,"",id);
        a[id]=a[id]","n[i];
    }
    # print everyhing
    for(i in a){
        print i""a[i];
    }
}'

편집: 내 첫 번째 답변이 질문에 올바르게 대답하지 못했습니다.

답변2

Perl이 구조에 옵니다:

#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

<>;  # Skip the header.

my %sum;
my %types;
while (<>) {
    my ($count, $id, $type) = grep length, split '[\s|]+';
    $sum{$id}{$type} += $count;
    $types{$type} = 1;
}

say join ',', 'id', sort keys %types;
for my $id (sort { $a <=> $b } keys %sum) {
    say join ',', $id, map $_ // q(), @{ $sum{$id} }{ sort keys %types };
}

여기에는 유형 테이블과 ID 테이블이라는 두 개의 테이블이 있습니다. 각 ID에 대해 각 유형의 합계를 저장합니다.

답변3

만약에GNU 데이터 혼합그렇다면 그건 당신을 위한 선택이에요

awk 'NR>1 {print $1, $2, $4}' OFS=, file | datamash -t, -s --filler=0 crosstab 2,3 sum 1
,1,2,3
10,0,0,588
12,0,0,10
14,0,0,883
17,0,0,98
18,17,0,77598
2,0,0,17892
21,0,0,10000
23,0,0,20000
27,0,0,63
3,0,0,6
35,0,0,2446
4,15,253,19871
5,0,0,1000

답변4

Perl을 사용하여 CSV 파일을 반복하고 그 과정에서 적절한 유형의 합계를 해시에 누적할 수 있습니다. 마지막으로, 각 ID별로 수집된 정보가 표시됩니다.

데이터 구조

%h = (
   ID1    =>  [ sum_of_type1, sum_of_type2, sum_of_type3 ],
   ...
)

이는 아래 코드를 이해하는 데 도움이 됩니다.

진주

perl -wMstrict -Mvars='*h' -F'\s+|\|' -lane '
   $, = chr 44, next if $. == 1;

   my($count, $id, $type) = grep /./, @F;
   $h{ $id }[ $type-1 ] += $count}{
   print $_, map { $_ || 0 } @{ $h{$_} } for sort { $a <=> $b } keys %h
' yourcsvfile

산출

2,0,0,17892
3,0,0,6
4,15,253,19871
5,0,0,1000
...

관련 정보