【问题标题】:Find overlap between two tables by multiple columns and substring通过多列和子字符串查找两个表之间的重叠
【发布时间】:2017-07-06 06:46:50
【问题描述】:

我想根据三列获得两个表之间的重叠。

文件 1

 Chr        B      C       Start  End   F   G   E    D   
chr1    HAVANA  gene    11869   14409   .   +   .   gene_id "ENSG00000223972.5"; gene_type "transcribed_unprocessed_pseudogene"; gene_status "KNOWN"; gene_name "DDX11L1"; level 2; havana_gene "OTTHUMG00000000961.2";
chr1    HAVANA  gene    100000  112000  .   +   .   gene_id "ENSG00000223972.5"; gene_type "transcribed_unprocessed_pseudogene"; gene_status "KNOWN"; gene_name "DDX11L1"; level 2; havana_gene "OTTHUMG00000000961.2";
chr3    HAVANA  gene    11870   14409   .   +   .   gene_id "ENSG00000223972.5"; gene_type "transcribed_unprocessed_pseudogene"; gene_status "KNOWN"; gene_name "DDX11L1"; level 2; havana_gene "OTTHUMG00000000961.2";
chr3    HAVANA  gene    11839   11869   .   +   .   gene_id "ENSG00000223972.5"; gene_type "transcribed_unprocessed_pseudogene"; gene_status "KNOWN"; gene_name "DDX11L1"; level 2; havana_gene "OTTHUMG00000000961.2";
chr2    HAVANA  gene    11869   14409   .   +   .   gene_id "ENSG00000223972.5"; gene_type "transcribed_unprocessed_pseudogene"; gene_status "KNOWN"; gene_name "DDX11L1"; level 2; havana_gene "OTTHUMG00000000961.2";

....

文件 2

 A                       B           Start  End    Chr          D  
ENSG00000177697     ENST00000525333 832986  833026  11          1
ENSG00000197283     ENST00000876382 100000  112000  1           1
ENSG00000194582     ENST00000184632 11869   14409   2           1
ENSG00000174528     ENST00000241053 154728  184728  12          1
ENSG00000103629     ENST00000816493 832986  917483  13          1 
ENSG00000183628     ENST00000816472 711633  782163  11          1
ENSG00000192748     ENST00000164924 832986  982732  CHK_1231    1
ENSG00000183643     ENST00000917473 183728  194873  3           1
ENSG00000183647     ENST00000184637 800000  819483  2           1
ENSG00000177697     ENST00000184627 100023  120000  11          1

期望的输出:

Chr        B      C       Start  End   F   G   E    D   
chr1    HAVANA  gene    100000  112000  .   +   .   gene_id "ENSG00000223972.5"; gene_type "transcribed_unprocessed_pseudogene"; gene_status "KNOWN"; gene_name "DDX11L1"; level 2; havana_gene "OTTHUMG00000000961.2";
chr2    HAVANA  gene    11869   14409   .   +   .   gene_id "ENSG00000223972.5"; gene_type "transcribed_unprocessed_pseudogene"; gene_status "KNOWN"; gene_name "DDX11L1"; level 2; havana_gene "OTTHUMG00000000961.2";

问题是文件 2 中第 5 列的数字是第一个文件的第 1 列的子字符串(因此它会说 chr11 而不是 11)。表 2 的第 4 列和第 5 列应等于文件 1(开始和结束)中的第 4 列和第 5 列。我希望输出与文件 1 完全相同,只是元素应与文件 2 中的元素相同。

我不熟悉 awk 语法,对我来说它并不直观,但我在浏览之前的帖子时发现这一行,我想可以扩展这个命令:

awk 'FNR==NR{a[$1]=$2 FS $3;next}{ print $0, a[$1]}' file2 file1 > file1_subset2

【问题讨论】:

  • edit 您的问题包括更多示例输入(匹配和不匹配的行)以及给定该输入的预期输出。
  • 问题是文件 2 第 5 列中的数字是第一个文件第 1 列的子字符串(因此,它会说 chr11 而不是 11)。 这个很混乱。 11 不是 chr1 的子字符串。 “它会说” 指的是什么?您是否在问题中交替使用 tablefile ?你是什​​么意思列“应该相等”

标签: unix awk terminal


【解决方案1】:

@ELHL:试试:

awk 'FNR==NR{sub(/[[:alpha:]]+/,"",$1);A[$1,$4,$5]=$0;next} {sub(/[[:alpha:]]+/,"",$(NF-1));} ((($NF-1),$3,$4) in A){print A[($NF-1),$3,$4]}'   SUBSEP=,   Input_file1  Input_file2

如果两者都符合您的要求,它将打印 file1 的值,请尝试然后告诉我。

现在也添加非单线形式的解决方案。

awk 'FNR==NR{
                sub(/[[:alpha:]]+/,"",$1);
                A[$1,$4,$5]=$0;
                next
            }
            {
                sub(/[[:alpha:]]+/,"",$(NF-1));
            }
     ((($NF-1),$3,$4) in A){
                                print A[($NF-1),$3,$4]
                           }
    '  SUBSEP=,    Input_file1  Input_file2

EDIT2:添加一个函数,我可以删除 2 次写入的 sub 实际上在不同的字段中执行相同的操作。

awk 'function remove_chars(a){sub(/[[:alpha:]]+/,"",$a)} FNR==NR{remove_chars($1);A[$1,$4,$5]=$0;next} {remove_chars($(NF-1));} ((($NF-1),$3,$4) in A){print A[($NF-1),$3,$4]}'  SUBSEP=, Input_file1   Input_file2

NON-one liner form of solution也如下。

awk 'function remove_chars(a){
                                sub(/[[:alpha:]]+/,"",$a)
                             }
     FNR==NR                 {
                                remove_chars($1);
                                A[$1,$4,$5]=$0;
                                next
                             }
                             {
                                remove_chars($(NF-1));
                             }
     ((($NF-1),$3,$4) in A)  {
                                print A[($NF-1),$3,$4]
                             }
   ' SUBSEP=,   Input_file1   Input_file2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-28
    • 2011-03-23
    • 2014-12-07
    • 1970-01-01
    • 1970-01-01
    • 2013-09-13
    相关资源
    最近更新 更多