すべての個々のグループ項目間のペアを構成する値のリストに基づいてグループを割り当てます。

すべての個々のグループ項目間のペアを構成する値のリストに基づいてグループを割り当てます。

ペアの項目を表示する2つの列を持つタブ区切りファイルがありますpairs.tsv。 2つの列の2つの値に基づいて3番目の列を作成し、アイテムにグループを割り当てようとしています。

ただし、場合によっては、複数の項目が同じグループに属します。したがって、スクリプトは行1から始めてgroup01最初のペアに割り当て、残りの行で列1または列2の2つの値のいずれかが発生することを確認し、trueの場合はそのgroup01行にも割り当てる必要があります。

繰り返し検索でペア付きファイルのすべての項目がgroup01割り当てられるまで、この手順を繰り返す必要がありますgroup01

その後、スクリプトは次の行に進み、まだ割り当てられていない場合はグループをグループに割り当て、group02行2の列1または2の項目が下の行に表示されたら、残りのファイルを再確認する必要があります。もしそうなら、それを割り当ててくださいgroup02。その行をください。など。

pairs.tsv:

a   b
c   d
e   f
e   g
h   i
h   j
k   l
f   g
m   n
i   j

出力ファイルは次のようにする必要があります。

a   b   group01
c   d   group02
e   f   group03
e   g   group03
h   i   group04
h   j   group04
k   l   group05
f   g   group03
m   n   group06
i   j   group04

ベストアンサー1

これはファイルを入力して一度だけ行うことができます。

awk -F'\t' '{ 
  # "groups" is an associative array containing the group numbers
  # for the values in fields $1 and $2.
  if (! ($1 in groups)) {
     # "gc" stands for "group counter"
     groups[$1] = ++gc;
  }

  groups[$2] = groups[$1]

  printf "%s\t%s\tgroup%02i\n", $1, $2, groups[$1];
}' pairs.tsv
a       b       group01
c       d       group02
e       f       group03
e       g       group03
h       i       group04
h       j       group04
k       l       group05
f       g       group03
m       n       group06
i       j       group04

%groups私はまた、awkバージョンのようにハッシュ(連想配列)を使用するPerlバージョンを作成しました。そして@pairs各グループのペアを維持するには、配列の配列配列(AoA - つまり、各要素が別の配列の配列)を呼び出します。結果を読み取ったとおりに印刷するのではなく、読み取った後にすべての入力を印刷します。

#!/usr/bin/perl

use strict;

my $gc = 1; # group counter
my %groups; # hash containing group numbers for each element
my @pairs;  # array of arrays containing pairs

while(<>) {
  chomp;
  my ($a,$b) = split /\t/;

  $groups{$a} = $gc++ unless (defined($groups{$a}));

  $groups{$b} = $groups{$a};
  push @{ $pairs[$groups{$a}] }, [ $a, $b ];
};

END {
  for my $g (keys @pairs) {
    for my $p (@{ $pairs[$g] }) {
      printf "%s\t%s\tgroup%02i\n", @$p[0], @$p[1], $g;
    }
  };
}

@pairs 配列を繰り返すので、出力はグループ番号に基づいてソートされます。

$ ./group.pl pairs.tsv 
a       b       group01
c       d       group02
e       f       group03
e       g       group03
f       g       group03
h       i       group04
h       j       group04
i       j       group04
k       l       group05
m       n       group06

ソートを除いて、両方のバージョンの出力は同じです。

おすすめ記事