![데이터를 그룹화하고 문자와 값을 새 범주에 할당](https://linux55.com/image/58612/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%A5%BC%20%EA%B7%B8%EB%A3%B9%ED%99%94%ED%95%98%EA%B3%A0%20%EB%AC%B8%EC%9E%90%EC%99%80%20%EA%B0%92%EC%9D%84%20%EC%83%88%20%EB%B2%94%EC%A3%BC%EC%97%90%20%ED%95%A0%EB%8B%B9.png)
탭으로 구분된 데이터에 4개의 열이 있고 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
설명이 필요하시면 댓글로 질문해주세요.