2017-04-09 48 views
0

一般问题: 我正在尝试使用索引查找基于参考表的名称。我的文档和参考表中的第一列的值需要匹配,但后来我想检查我的文件中的数值,在我的参考表中的两个数值列之间下降。如果是这样,我想从参考表中打印相应的名称到我的文件中的新列。否则,我想打印“NA”多列查找

具体例子 我想匹配我的文件和参考表的第一列(CHR),看看它们是否匹配。如果是这样,我想看看在文件(POS)的第2列的值大于所述基准(开始)的3列,但小于基准(完)的4列中。如果是这样,我想从参考表中添加相应的col 4(Gene_name)到我的文件的新的第4列。如果没有相应的基因,我想把“NA”放在我的文件的基因名称列中。

文件

Chr pos  p-val 
2L 1885826 2.638e-08 
2L 1996567 5.12e-05 
2L 2360597 9.472e-05 
2R 2360621 9.472e-05 
2R 2360623 9.472e-05 

参考

Chr Start End  Gene_name 
2L 1884260 1888828 FBgn0262029 
2L 19531851 19547482 FBgn0052532 
2L 2350523 2361570 FBgn0023536 
2L 4647871 4648646 FBgn0029718 

所需的输出

Chr pos  p-val  Gene_name 
2L 1885826 2.638e-08 FBgn0262029 
2L 1996567 5.12e-05 NA 
2L 2360597 9.472e-05 FBgn0023536 
2R 2360621 9.472e-05 NA 
2R 2360623 9.472e-05 NA 

尝试

我一直在试图从这个问题调整代码来做到这一点。 awk Lookup 2 files, print match and Sum of Sencond Field:

到目前为止,我有这样的:

awk -F"\t" '          #Set Field separator to  "\t" 
FNR==NR {a[$1];a[$2];a[$3];next}     #Read data from Reference using field #1, field #2, field #3 as index in to array a 
{if ($1 in a)        #Test if field #1 in Table is found in a 
{if ($2 > a[$2]) 
{if ($2 < a[$3]) 
print $0, a[$4]      #If found, print line of f1.txt with sum and index from array 
else print $0,"NA"  #If not found print line of f1.txt with NotFound 
} 
else print $0,"NA"  #If not found print line of f1.txt with NotFound 
} 
else print $0,"NA"  #If not found print line of f1.txt with NotFound 
} 
' OFS="\t" Referance.txt File.txt      #Set Output field separator to , and read files 

产生

2L 1885826 2.638e-08 NA 
2L 1996567 5.12e-05 NA 
2L 2360597 9.472e-05 NA 
2R 2360621 9.472e-05 NA 
2R 2360623 9.472e-05 NA 

我想我在嵌套if else语句犯了一个错误的地方,但我不知道是什么我做错了。将不胜感激任何建议!

回答

1

awk来救援!

awk  '{k=$1} 
    NR==FNR {c[k]++; start[k,c[k]]=$2; end[k,c[k]]=$3; gene[k,c[k]]=$4; next} 
      {$(NF+1)=FNR==1?"Gene_name":"NA"} 
    k in c {for(i=1;i<=c[k];i++) 
       if(start[k,i]<=$2 && $2<=end[k,i]) 
        {$NF=gene[k,i]; 
        break}}1' file2 file1 | column -t 


Chr pos  p-val  Gene_name 
2L 1885826 2.638e-08 FBgn0262029 
2L 1996567 5.12e-05 NA 
2L 2360597 9.472e-05 FBgn0023536 
2R 2360621 9.472e-05 NA 
2R 2360623 9.472e-05 NA 

一些说法:假设第二个文件适合内存,范围不重叠(如果是的话,只报告第一个匹配项)。是否线性扫描,如果两个文件较大,因此可能是缓慢的,更好的算法可以与排序的区间开始(也将验证他们是否重叠或没有)。

代码应该很容易阅读,基本上是加载了完整的文件2成多个阵列和检查的第一个文件的条目匹配范围。