If statement 按多列查找
一般问题: 我正在尝试使用索引根据引用表查找名称。文档和引用表中第一列的值需要匹配,但是我想检查文件中的数值是否位于引用表中的两个数值列之间。如果是这样,我想将引用表中相应的名称打印到文件中的新列中。否则,我想打印NA 具体例子 我想匹配文件的第一列Chr和引用表,看看它们是否匹配。如果是这样,我想看看文件pos的第2列中的值是否大于引用开始的第3列,但小于引用结束的第4列。如果是这样,我想将引用表中相应的col 4 Gene_名称添加到文件的新第4列。如果没有相应的基因,我想把NA放在我的文件的genename列中 文件 参考文献If statement 按多列查找,if-statement,awk,If Statement,Awk,一般问题: 我正在尝试使用索引根据引用表查找名称。文档和引用表中第一列的值需要匹配,但是我想检查文件中的数值是否位于引用表中的两个数值列之间。如果是这样,我想将引用表中相应的名称打印到文件中的新列中。否则,我想打印NA 具体例子 我想匹配文件的第一列Chr和引用表,看看它们是否匹配。如果是这样,我想看看文件pos的第2列中的值是否大于引用开始的第3列,但小于引用结束的第4列。如果是这样,我想将引用表中相应的col 4 Gene_名称添加到文件的新第4列。如果没有相应的基因,我想把NA放在我的文件
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 -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
我认为我在嵌套的if-else语句中的某个地方犯了错误,但我不确定我做错了什么。如果您有任何建议,我们将不胜感激 快来营救
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
备注:假设第二个文件适合内存,并且范围不重叠,如果是,则只报告第一个匹配。进行线性扫描,因此如果其中一个文件较大,则速度可能较慢,更好的算法可能从排序范围开始,同时也将验证它们是否重叠
代码应该易于阅读,基本上是将完整的file2加载到多个数组中,并检查第一个文件的条目是否匹配范围
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
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