事前に整列されたタブで区切られたファイルをマージしたいと思います。
- 文書
bygroup.0
:ancient-american mercury 1 164 ancient-american mh25 2 8717664 ancient-neolith tk11 262 40074321970 ancientdna jk21 6936 17069206689 ancientdna rm20 11267 372606702813 ancientgen ab34 1573 27800468142 ancientgen dg11 3516 45081427920 ancientgen fa8 7179 462396221983 ancientgen mp15 41 10248223517 ancientgen mp18 254 1049351143 ancientgen rm20 15100 1565340401 ancientgen tc9 1695 89861489631
- 文書
bygroup.2
:ancient-american mercury 1 160 ancient-american mh25 2 10362712888 ancient-neolith tk11 264 43842268110 ancientdna jk21 6919 16379509855 ancientdna rm20 11268 324906365415 ancientgen ab34 1577 33947364202 ancientgen dg11 3518 48092138390 ancientgen fa8 7174 472364587220 ancientgen mp15 39 32487920045 ancientgen mp18 254 1058177852 ancientgen rm20 15104 998615135 ancientgen tc9 1692 94858351562
どちらのファイルも同じ行数を持ち、列1と2に基づいて同じ順序で、その列の項目が同じであることがわかります。
さて、最初の2つの列の値が同じすべての行が順番に出力されるようにマージしたいと思います。
sort -m
私はこれが私に必要なものだと思いましたが、
$ sort -m bygroup.*
ancient-american mercury 1 160
ancient-american mercury 1 164
ancient-american mh25 2 10362712888
ancient-american mh25 2 8717664
ancient-neolith tk11 262 40074321970
ancientdna jk21 6936 17069206689
ancientdna rm20 11267 372606702813
ancientgen ab34 1573 27800468142
ancientgen dg11 3516 45081427920
ancientgen fa8 7179 462396221983
ancientgen mp15 41 10248223517
ancientgen mp18 254 1049351143
ancientgen rm20 15100 1565340401
ancientgen tc9 1695 89861489631
ancient-neolith tk11 264 43842268110
ancientdna jk21 6919 16379509855
ancientdna rm20 11268 324906365415
ancientgen ab34 1577 33947364202
ancientgen dg11 3518 48092138390
ancientgen fa8 7174 472364587220
ancientgen mp15 39 32487920045
ancientgen mp18 254 1058177852
ancientgen rm20 15104 998615135
ancientgen tc9 1692 94858351562
(私が追加した他のオプションでも同じ結果を得ました。... sort -k 1,2 -ifm
)
それは古代アメリカ人への私の期待に応えますが、他の人にとってはそうではありません。何が起こっているのか、完全な整列(sort
ここでは必要なく動作します-m
)に頼らずにこれを行うための別の迅速で効率的な方法はありますか?
答え1
TXR Lispソリューション:
$ txr merge.tl
ancient-american mercury 1 164
ancient-american mercury 1 160
ancient-american mh25 2 8717664
ancient-american mh25 2 10362712888
ancient-neolith tk11 262 40074321970
ancient-neolith tk11 264 43842268110
ancientdna jk21 6936 17069206689
ancientdna jk21 6919 16379509855
ancientdna rm20 11267 372606702813
ancientdna rm20 11268 324906365415
ancientgen ab34 1573 27800468142
ancientgen ab34 1577 33947364202
ancientgen dg11 3516 45081427920
ancientgen dg11 3518 48092138390
ancientgen fa8 7179 462396221983
ancientgen fa8 7174 472364587220
ancientgen mp15 41 10248223517
ancientgen mp15 39 32487920045
ancientgen mp18 254 1049351143
ancientgen mp18 254 1058177852
ancientgen rm20 15100 1565340401
ancientgen rm20 15104 998615135
ancientgen tc9 1695 89861489631
ancientgen tc9 1692 94858351562
パスワード:
(defstruct record ()
key
line
(:method equal (me) me.key))
(defun read-recs (file)
(build
(awk (:set fs "\t")
(:inputs file)
(t (add (new record
key [f 0..2]
line rec))))))
(mapdo [chain .line put-line] (merge (read-recs "bygroup.0") (read-recs "bygroup.1")))
ファイル内の各レコードに関する情報を保持するために、ソートキーrecord
aと生の軸行であるaを含む構造体の種類を定義します。スロットは2つの文字列のリストになります。key
line
key
このrecord
タイプには、equal
次を実装するメソッドがあります。同等の代替。つまり、record
関数が渡されるかequal
オブジェクトless
が比較されるたびに、オブジェクトのgreater
代わりにそのメソッドの値が使用されます。たとえば、比較関数を指定せずにsort
構造体リストにアクセスすると、record
その構造体はキーに基づいてソートされます。
この関数は、read-recs
標準awk
Awkのフィールド区切り文字を"\t" (tab). For each record, the
t condition (unconditional truth) dispatches an action which creates a record object. The
key is a sublist of the
f (field) list, consisting of the first two fields. The
line is the
rec $ 0`として指定します。: the whole record.
is like
このbuild
マクロは、暗黙的、手続き型リストの作成に使用されます。たとえば、(build (add 1) (add 2))
リストが返されます(1 2)
。終了時に返されるbuild
暗黙の隠しリストに呼び出しが追加される範囲を作成します。add
build
read-recs
等値置換を使用すると、必要なキーを正しく入力するタイプがあるため、両方のファイルを読み取り、ソートされたリストを取得するために関数にrecord
渡すだけです。merge
record
このリストのオブジェクトは、2 つの関数の接続を介してマップされます。[chain .line put-line]
この関数はオブジェクトのスロットを.line
検索し、それを標準出力にダンプし、その後に改行文字が続きます。line
put-line
read-recs
andを使わずにbuild
関数を実装する方法は次のawk
とおりです。
(defun read-recs (file)
(collect-each ((line (file-get-lines file)))
(let ((fields (spl #\tab line)))
(new record key [fields 0..2]
line line))))
答え2
Rプログラミング言語の使用
1つ以上の空白文字を単一のタブ文字に置き換えて、テキストファイルを保存します。 2つのデータファイルをRに読み込みます。
> group0 <- read.delim("/Users/admin/bygroup.0", header=FALSE)
> group2 <- read.delim("/Users/admin/bygroup.2", header=FALSE)
> head(group0)
V1 V2 V3 V4
1 ancient-american mercury 1 164
2 ancient-american mh25 2 8717664
3 ancient-neolith tk11 262 40074321970
4 ancientdna jk21 6936 17069206689
5 ancientdna rm20 11267 372606702813
6 ancientgen ab34 1573 27800468142
> head(group2)
V1 V2 V3 V4
1 ancient-american mercury 1 160
2 ancient-american mh25 2 10362712888
3 ancient-neolith tk11 264 43842268110
4 ancientdna jk21 6919 16379509855
5 ancientdna rm20 11268 324906365415
6 ancientgen ab34 1577 33947364202
データファイルをマージするには、Rのmerge()
機能を使用します。
> merge(group0, group2, by = c("V1","V2"))
V1 V2 V3.x V4.x V3.y V4.y
1 ancient-american mercury 1 164 1 160
2 ancient-american mh25 2 8717664 2 10362712888
3 ancient-neolith tk11 262 40074321970 264 43842268110
4 ancientdna jk21 6936 17069206689 6919 16379509855
5 ancientdna rm20 11267 372606702813 11268 324906365415
6 ancientgen ab34 1573 27800468142 1577 33947364202
7 ancientgen dg11 3516 45081427920 3518 48092138390
8 ancientgen fa8 7179 462396221983 7174 472364587220
9 ancientgen mp15 41 10248223517 39 32487920045
10 ancientgen mp18 254 1049351143 254 1058177852
11 ancientgen rm20 15100 1565340401 15104 998615135
12 ancientgen tc9 1695 89861489631 1692 94858351562
write.delim()
または、関数を使用してデータを書き換えることもできますwrite.csv()
。ヘルプを表示するには、プロンプトで、?getwd()
またはなどの疑問符の前にコマンドを入力します?setwd()
。?read.delim()
?merge()
[注:Rのインストール期間によっては、stringsAsFactors=FALSE
すべての関数呼び出しread.delim()
にこの引数を含める必要があります。]
https://www.r-project.org/
https://cran.r-project.org/index.html