我有三個數據框:
數據框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
我想獲得一個最終資料幀,其中根據第一個資料幀的第四列,將報告與第二個和第三個資料幀的第四列相關的匹配或不匹配。在新的資料幀中,如果存在匹配,則將報告相同的 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
你的第二個、第三個和第一個數據框分別文件FILENAME
- 內建變數指向目前處理的檔案的名稱ARGV
- 指向傳遞給 awk 腳本的所有參數的內建變數。即ARGV[1]
包含df2
FILENAME == ARGV[1] && NR>1
- 遇到第一個檔案(即df2
從第二行開始)df2[$2,$3,$4]
- 從“獲取關鍵價值”數據框2" 作為數組的鍵df2
FILENAME == ARGV[2] && FNR>1
df3
- 遇到從第二行開始的第二個檔案(即)df3[$2,$3,$4]
- 從“獲取關鍵價值”數據框3" 作為數組的鍵df3
FILENAME == ARGV[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 已填入所有第四列,IOW,沒有遺失。
- 我們
Perl
以行讀入+自動分割模式呼叫:perl -lane
- 在讀取第3幀期間,@ARGV有2個元素,在第2幀期間讀取1個元素,在第3幀期間讀取0個元素。
- 我們填入一個雜湊值
%h
,其鍵是第 2+3 個字段,$F[1],$F[2]
值是匿名數組引用,因此稱為:$h{...}[...]
。 - 在第一個資料幀(@ARGV有0個元素)期間,我們用第一個資料幀的內容列印每一行,並確定對應當前第二個資料幀的第二/第三幀的陣列元素是否存在/第三個字段。