順序を表示せずに列値を一致させる

順序を表示せずに列値を一致させる

順序を見ずに2つの列の値を比較しようとしています。値を合計し、一致する場合は一致し、追加の列に「一致」、それ以外の場合は「一致しない」を入れてみました。しかし、ここでの問題は、2つの数字の合計が同じである可能性があることです。たとえば、次のようになります。

ダミーのアイデア(リストがかなり長いので、これが起こる可能性があると思います):

7+5=12;  5+7=12 = Match
6+6=12;  4+8=12 = Nomatch in theory while seeing the numbers but summing them showing the Match.

    locus   truth   predicted
CSF1PO_007-BC03_20171027_2149   11,12   11,12
CSF1PO_007-BC04_20171027_2149   11,12   11,12
CSF1PO_19_20171027_2149 10,12   12,10
CSF1PO_20_20171027_2149 10,0    10,11
CSF1PO_A-10_2018123_1836    12,0    12,13
CSF1PO_A-11_2018123_1836    10,12   12,10
CSF1PO_A-1_20181222_0036    10,11   10,11
CSF1PO_A-12_2018123_1836    11,12   11,12
CSF1PO_A-13_2018123_1836    8,10    10,8
CSF1PO_A-14_2018123_1836    8,11    8,11

これまでの合計と一致を試してみました。

cat test | sed '1d' | sed 's/,/\t/g' | awk '{print $1"\t"$2+$3"\t"$4+$5}' | awk '{ if ($2 == $3) print $1"\t"$2"\t"$3"\t""Match"; else print  $1"\t"$2"\t"$3"\t""NoMatch"}'

Output:
CSF1PO_007-BC03_20171027_2149   23  23  Match
CSF1PO_007-BC04_20171027_2149   23  23  Match
CSF1PO_19_20171027_2149 22  22  Match
CSF1PO_20_20171027_2149 10  21  NoMatch
CSF1PO_A-10_2018123_1836    12  25  NoMatch
CSF1PO_A-11_2018123_1836    22  22  Match
CSF1PO_A-1_20181222_0036    21  21  Match
CSF1PO_A-12_2018123_1836    23  23  Match
CSF1PO_A-13_2018123_1836    18  18  Match
CSF1PO_A-14_2018123_1836    19  19  Match

注:また、覚えておくべき1つのことは、他の列の値と一致する数字は「一致」と見なすことができることです。

Example:
CSF1PO_20_20171027_2149 10,0    10,11 === Match as one number matches (order does not matter)
CSF1PO_A-10_2018123_1836    12,0    12,13 === Match as one number matches (order does not matter)

私が試した1つの可能な解決策はうまくいくようですが、説明や他の可能な解決策が必要です。

cat test | sed '1d' | sed 's/,/\t/g' | awk '{ if ($2 == $4 || $2 == $5) print $0 , "=>", "Match"; else if ($3 == $5 || $3 == $4) print $0 , "=>", "Match"; else print $0,"=>","Nomatch"}'

CSF1PO_007-BC03_20171027_2149   11  12  11  12 => Match
CSF1PO_007-BC04_20171027_2149   11  12  11  12 => Match
CSF1PO_19_20171027_2149 10  12  12  10 => Match
CSF1PO_20_20171027_2149 10  0   10  11 => Match
CSF1PO_A-10_2018123_1836    12  0   12  13 => Match
CSF1PO_A-11_2018123_1836    10  12  12  10 => Match
CSF1PO_A-1_20181222_0036    10  11  10  11 => Match
CSF1PO_A-12_2018123_1836    11  12  11  12 => Match
CSF1PO_A-13_2018123_1836    8   10  10  8 => Match
CSF1PO_A-14_2018123_1836    8   11  8   11 => Match

私がこれをしっかりしていることを説明する必要があります。ありがとう

ベストアンサー1

私の考えでは、あなたの行の構造は次のとおりです。最初のスペースの前にランダムなテキストがある行です。次に、スペースで区切られた2つのフィールドがあります。各フィールドは、カンマで区切られた2つの数字で構成されています。また、最初のスペースの前のテキストにはカンマがないようです。

パイプラインの最初の部分はよさそうです。したがって、実行後に上記の仮説が正しい場合は、cat test | sed '1d' | sed 's/,/\t/g' > test2ヘッダー行を削除し、スペースで区切られたファイルは5つだけ残ります。フィールド 2 と 3 は最初の数値ペア、フィールド 4 と 5 は 2 番目の数値ペアです。

あなたの質問は明らかであるので、これは再び私の部分について少し推測です。フィールド 2 と 3 のいずれかまたは両方を一致させるには、フィールド 4 と 5 のいずれかまたは両方と同じでなければなりません。そのうち、どの一致があるかは重要ではありません(一致する必要がある順序ペアとは見なされません)。

したがって、2つではなく1つのawkフラグメントしか使用できません。

awk '($2==$4 || $2==$5 || $3==$4 || $3==$5) { print $0 " Match" }' < test2

1つのawkスクリプトでこれを行うこともできます。これは、スペースとカンマを使用してフィールドを区切り、最初の行を無視するようにawkに指示できるためです。

# -F changes the input field seperator
awk -F '[[:space:],]' '
  # remove the first line
  NR==1 {next}
  # execute block if any of these field combinations match
  ($2==$4 || $2==$5 || $3==$4 || $3==$5) { print $0 " Match" }
  # reverse the condition and print stuff for not matching lines
  ($2!=$4 && $2!=$5 && $3!=$4 && $3!=$5) { print $0 " Nomatch" }
' < test

おすすめ記事