Text-Processing
如何為具有重疊區域的間隔分配值?
我有兩個大文件,第一個文件包含一些 85K 行的間隔:
head data.intervals id id_uniq numberA numberB 1 g1 5 20 1 g2 6 29 1 g3 17 35 1 g4 37 46 1 g5 50 63 1 g6 70 95 1 g7 87 93 2 g8 3 15 2 g9 10 33 2 g10 60 77 2 g11 90 132
第二個文件包含一些超過 200 萬行的位置:
head data.posiitons id number 1 4 1 19 1 36 1 49 1 90 2 1 2 20 2 89 2 93 2 120
我想做的是:對於位置文件“number”列中的每個值,搜尋它是否等於或介於 data.intervals 文件的“numberA”和“numberB”對值中的任何一個。
此外,對於這個“numberA”和“numberB”對值,其各自的“id”必須與 data.position 中的“id”匹配。如果這都是真的,那麼我想將 data.intervals 中的相應“id.uniq”插入到 data.posiitons 文件中相應行的列中。
這裡還有另一個問題:其中一些區間相互重疊,一個位置可能落在 2 個或超過 2 個區間的範圍內。我想將它們分別分配給每個間隔。
這是我希望得到的最終輸出(NA 表示位置不在任何間隔範圍內):
id number assigned1 1 4 NA 1 19 g1,g2,g3 1 36 NA 1 49 NA 1 90 g6,g7 2 1 NA 2 20 g9 2 89 NA 2 93 g11 2 120 g11
是否有任何解決方案可以使用 bash 或 perl 腳本完成此任務?
您可以
Perl
使用以下方法執行此操作:$ perl -lane ' my($id, $uniq_id, $lower, $upper) = @F; $h{$id}{$uniq_id}{MIN} = $lower; $h{$id}{$uniq_id}{MAX} = $upper; push @{$order{$id}}, $uniq_id; }{ while(<STDIN>) { chomp; my($id, $number) = split; print join "\t", $id, $number, join(",", grep { $h{$id}{$_}{MIN} < $number and $h{$id}{$_}{MAX} > $number } @{$order{$id}}) || qw/NA/;; } ' data.intervals < data.posiitons
輸出:
1 4 NA 1 19 g1,g2,g3 1 36 NA 1 49 NA 1 90 g6,g7 2 1 NA 2 20 g9 2 89 NA 2 93 g11 2 120 g11
作品:
- 首先讀取間隔文件並建構以 ID、唯一 ID 為鍵並包含範圍端點的雜湊的資料結構。
- 散列以相同的
%order
順序儲存出於播放目的而遇到唯一 ID 的順序。OTW,雜湊排序是隨機的。- 接下來讀取位置文件並首先解壓縮每個記錄(或行)並將它們放入 $ id and $ 數標量。
grep
應選擇滿足數字在範圍內的約束的唯一 ID。否則"NA"
通過。