데이터를 그룹화하고 문자와 값을 새 범주에 할당

데이터를 그룹화하고 문자와 값을 새 범주에 할당

탭으로 구분된 데이터에 4개의 열이 있고 2단계를 수행해야 합니다.

  1. 처음 2개 열의 조합을 기준으로 데이터를 그룹화합니다.
  2. 특정 그룹(col2)의 연결된 값(col 4)에서 새로운 값 조합이 발생할 때마다 해당 행에 알파벳순과 숫자순으로 새 카테고리를 할당해야 합니다. 이전에 조합이 발견된 경우 해당 카테고리가 지정됩니다.

입력 파일은 다음과 같습니다

Line    Group   Name    Value
L1  G1  AX27    A
L1  G1  AX25    T
L1  G1  AX356   G
L1  G2  1X87    C
L1  G2  AX78    A
L1  G2  AX987   A
L1  G2  AX001B  A
L1  G3  A2XTR1  A
L1  G3  A2XTR2  T
L2  G1  AX27    A
L2  G1  AX25    T
L2  G1  AX356   C
L2  G2  1X87    G
L2  G2  AX78    T
L2  G2  AX987   A
L2  G2  AX001B  A
L2  G3  A2XTR1  A
L2  G3  A2XTR2  T
L3  G1  AX25    T
L3  G1  AX356   G
L3  G2  AX987   A
L3  G2  AX001B  A
L3  G3  A2XTR1  A
L3  G3  A2XTR2  C
L4  G1  AX27    A
L4  G1  AX25    T
L4  G1  AX356   G
L4  G3  A2XTR1  A
L4  G3  A2XTR2  C
L5  G3  A2XTR1  A
L5  G3  A2XTR2  T

중간 출력 파일은 다음과 같습니다.

Line    Group   Collapsednames  Collapsedvalues
L1  G1  AX27 AX25 AX356 A T G 
L2  G1  AX27 AX25 AX356 A T C
L3  G1  AX25 AX356  T G
L4  G1  AX27 AX25 AX356 A T G 
L1  G2  1X87 AX78 AX987 AX001B  C A A A
L2  G2  1X87 AX78 AX987 AX001B  G T A A 
L3  G2  AX987 AX001B    A A
L1  G3  A2XTR1 A2XTR2   A T
L2  G3  A2XTR1 A2XTR2   A T
L3  G3  A2XTR1 A2XTR2   A C
L4  G3  A2XTR1 A2XTR2   A C
L5  G3  A2XTR1 A2XTR2   A T

모든 행(L1~L4)에 대해 G1에는 3가지 조합(ATG, ATC, TG)이 있으며, 여기서 조합(ATG)이 반복됩니다. 따라서 A가 두 번 나타나는 모든 조합에 문자 범주 A, B, C를 할당할 수 있습니다.

최종 출력은 다음과 같습니다.

Line    Group   Collapsednames  Collapsedvalues Alpha_Category  Number_Category
L1  G1  AX27 AX25 AX356 A T G   A   1
L2  G1  AX27 AX25 AX356 A T C   B   2
L3  G1  AX25 AX356  T G C   3
L4  G1  AX27 AX25 AX356 A T G   A   1
L1  G2  1X87 AX78 AX987 AX001B  C A A A A   1
L2  G2  1X87 AX78 AX987 AX001B  G T A A     B   2
L3  G2  AX987 AX001B    A A C   3
L1  G3  A2XTR1 A2XTR2   A T A   1
L2  G3  A2XTR1 A2XTR2   A T A   1
L3  G3  A2XTR1 A2XTR2   A C B   2
L4  G3  A2XTR1 A2XTR2   A C B   2
L5  G3  A2XTR1 A2XTR2   A T A   1

이것은 시도한 1단계이지만 작동하지 않았습니다. 1단계를 알아낸 후 2단계를 어떻게 해야 할지 모르겠습니다.

awk -F"\t" '{if(a[$1$2]){a[$1$2]=a[$1$2]" "$3" "$4} else { a[$1$2]=$3"\t$4}} END {for (i in a) {print i"|"a[i]}}' file

답변1

보기만큼 쉽지는 않습니다. Perl 솔루션에서는 코드를 이해하기 쉽게 만들기 위해 좀 더 자세하게 설명하려고 노력했습니다. 중첩된 데이터 구조(해시 해시, 배열 해시)에 대한 기본 지식이 필요합니다.

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

my (%collapsed, %groups);

<>;  # Skip header.
while (<>) {
    my ($line, $group, $name, $value) = split;
    push @{ $collapsed{$line}{$group}{names}  }, $name;
    push @{ $collapsed{$line}{$group}{values} }, $value;
    undef $groups{$group};
}

for my $group (sort keys %groups) {
    for my $line (sort keys %collapsed) {
        next unless $collapsed{$line}{$group};
        my $value = join q(), @{ $collapsed{$line}{$group}{values} };
        $groups{$group}{$value} ||= keys %{ $groups{$group} };
    }
}

for my $group (sort keys %groups) {
    for my $line (sort keys %collapsed) {
        next unless $collapsed{$line}{$group};
        my $value = join q(), @{ $collapsed{$line}{$group}{values} };
        say join "\t", $line, $group,
            join(' ', @{ $collapsed{$line}{$group}{names}  }),
            join(' ', @{ $collapsed{$line}{$group}{values} }),
            chr $groups{$group}{$value} - 1 + ord 'A',
            $groups{$group}{$value},
    }
}

답변2

Awk솔루션(많은 연관 배열) 그러나:

#!/usr/bin/awk

BEGIN {
SUBSEP=" "
split("A1^B2^C3^D4^E5",c,"^")
}

NR != 1 {
L[$1]=1
G[$2]=1
a[$1,$2]=a[$1,$2]" "$3
b[$1,$2]=b[$1,$2]" "$4
}

END {
for (g in G)
  {
  i=1
  for (l in L)
    {
    idx=b[l,g]
    if(d[idx]=="")
      d[idx]=c[i++]
    }
  } 
for (k in a)
  print k a[k] b[k],d[b[k]]
}

위 스크립트를 실행합니다.

awk -f script.awk tab.data | sort -k2,2 -k1,1

설명이 필요하시면 댓글로 질문해주세요.

관련 정보