3 つのデータ フレームがあります。
データフレーム 1
chr start end Id chr1 1 400 SN_1 chr1 401 800 SN_2 chr1 801 1200 SN_3 chr1 1201 1600 SN_4 chr1 1601 2000 SN_5 chr1 2001 2400 SN_6 chr1 2401 2800 SN_7
データフレーム 2
chr start end Id chr1 401 800 SN_2 chr1 801 1200 SN_3 chr1 1201 1600 SN_4
データフレーム 3
chr start end Id chr1 1201 1600 SN_4 chr1 1601 2000 SN_5 chr1 2001 2400 SN_6
そして、1 番目のデータ フレームの 4 列目に応じて、2 番目と 3 番目のデータ フレームの 4 列目との一致または不一致が報告される最終データ フレームを取得したいと思います。新しいデータ フレームでは、一致が存在する場合は同じ ID が報告されますが、一致が存在する場合は ID 名が NA に置き換えられます。入力と出力のみを記述する方が理解しやすいかもしれません。次のようになります。
望ましい出力:
chr start end Id Id Id chr1 1 400 SN_1 NA NA chr1 401 800 SN_2 SN_2 NA chr1 801 1200 SN_3 SN_3 NA chr1 1201 1600 SN_4 SN_4 SN_4 chr1 1601 2000 SN_5 NA SN_5 chr1 2001 2400 SN_6 NA SN_6 chr1 2401 2800 SN_7 NA NA
Unix コマンドで join を試しましたが、異なるサイズのデータ フレームを比較できません。何かアイデアがあれば、ぜひ教えてください。
答え1
awk解決:
awk 'FILENAME == ARGV[1] && NR>1{ df2[$2,$3,$4] }
FILENAME == ARGV[2] && FNR>1{ df3[$2,$3,$4] }
FILENAME == ARGV[3]{ if(FNR == 1) { printf("%s\t%s\t%s\n",$0,$NF,$NF) }
else { printf("%s\t%s\t%s\n",$0, (($2,$3,$4) in df2)? $NF :"NA",(($2,$3,$4) in df3)? $NF :"NA")}
}' df2 df3 df1 | column -t
出力:
chr start end Id Id Id
chr1 1 400 SN_1 NA NA
chr1 401 800 SN_2 SN_2 NA
chr1 801 1200 SN_3 SN_3 NA
chr1 1201 1600 SN_4 SN_4 SN_4
chr1 1601 2000 SN_5 NA SN_5
chr1 2001 2400 SN_6 NA SN_6
chr1 2401 2800 SN_7 NA NA
df2
、df3
そしてdf1
あなたの2番目、3番目、そして1番目ですデータフレームそれぞれファイルFILENAME
- 現在処理中のファイルの名前を指す組み込み変数ARGV
- awkスクリプトに渡されるすべての引数を指す組み込み変数。つまり、次のものARGV[1]
が含まれます。df2
FILENAME == ARGV[1] && NR>1
df2
- 2行目から始まる最初のファイル(つまり)に遭遇するdf2[$2,$3,$4]
- 「」から重要な値をキャプチャしますデータフレーム 2" 配列のキーとしてdf2
FILENAME == ARGV[2] && FNR>1
df3
- 2行目から始まる2番目のファイル(つまり)に遭遇するdf3[$2,$3,$4]
- 「」から重要な値をキャプチャしますデータフレーム 3" 配列のキーとしてdf3
FILENAME == ARGV[3]
- 3番目のファイル(つまりdf1
)に遭遇すると、メインデータフレーム
答え2
perl -lane '$,="\t";
!@ARGV and $. == 1 and print($_, qw/Id/x2),next;
$h{$F[1],$F[2]}->[@ARGV] = $F[3];
!@ARGV and print $_, map { $h{$F[1],$F[2]}->[$_] // q/NA/ } 1..2;
$. = 0 if eof;
' file3 file2 file1
結果
chr start end Id Id Id
chr1 1 400 SN_1 NA NA
chr1 401 800 SN_2 SN_2 NA
chr1 801 1200 SN_3 SN_3 NA
chr1 1201 1600 SN_4 SN_4 SN_4
chr1 1601 2000 SN_5 NA SN_5
chr1 2001 2400 SN_6 NA SN_6
chr1 2401 2800 SN_7 NA NA
仕組み
- 入力の順序は、dataframe3、dataframe2、dataframe1 です。
- dataframe1 の 4 番目の列がすべて入力されている (つまり、欠落している列がない) と仮定します。
Perl
行読み込み+自動分割モードで呼び出します:perl -lane
- 3 番目のフレームが読み込まれている間、@ARGV には 2 つの要素があり、2 番目のフレームが読み込まれている間は 1 つの要素があり、3 番目のフレームでは 0 です。
- ハッシュ を作成します。
%h
ハッシュのキーは 2 番目と 3 番目のフィールドで、$F[1],$F[2]
値は匿名配列参照であるため、 と呼ばれます$h{...}[...]
。 - 1 番目のデータ フレーム (要素が 0 個) の間、各行に 1 番目のデータ フレームの内容を出力し、対応する現在の 2 番目/3 番目のフィールドの 2 番目/3 番目のフレームに配列要素が存在するかどうかを判断します。