我有以下两个文件:
文件1:
1 290 rs1345
2 450 rs5313
1 1120 rs4523
2 790 rs4325
文件2:
1 201 LDLR
2 714 APOA5
1 818 NOTCH5
1 514 TTN
我希望仅隔离文件2中的第二个字段在文件1中第二个字段的100个单位内的行(如果字段1匹配):
所需的输出:(注意第三个字段来自file1中的匹配行)。
1 201 LDLR rs1345
2 714 APOA5 rs4325
我尝试使用以下代码:
for i in {1..4} #there are 4 lines in file2
do
chr=$(awk 'NR=="'${i}'" { print $1 }' file2)
pos=$(awk 'NR=="'${i}'" { print $2 }' file2)
gene=$(awk 'NR=="'${i}'" { print $3 }' file2)
start=$(echo $pos | awk '{print $1-100}') #start and end variables for 100 unit range
end=$(echo $pos | awk '{print $1+100}')
awk '{if ($1=="'$chr'" && $2 > "'$start'" && $2 < "'$end'") print "'$chr'","'$pos'","'$gene'"$3}' file1
done
代码不起作用,我相信我的开始和结束变量有问题,因为当我回显$ start时,我得到414,这对我没有意义,当我回显$时,我得到614端。
我理解这个问题可能难以理解,所以请问我是否需要澄清。
谢谢。
答案 0 :(得分:2)
难点在于1美元不是唯一的密钥,因此需要对数据结构采取一些措施来将数据存储在文件1中。
使用GNU awk,您可以使用数组数组:
gawk '
NR==FNR {f1[$1][$2] = $3; next}
$1 in f1 {
for (val in f1[$1])
if (val-100 <= $2 && $2 <= val+100)
print $0, f1[$1][val]
}
' file1 file2
否则,您必须使用一维数组并将2条信息填入密钥:
awk '
NR==FNR {f1[$1,$2] = $3; next}
{
for (key in f1) {
split(key, a, SUBSEP)
if (a[1] == $1 && a[2]-100 <= $2 && $2 <= a[2]+100)
print $0, f1[key]
}
}
' file1 file2
适用于mawk和nawk(和gawk)
答案 1 :(得分:0)
#!/usr/bin/python
import pandas as pd
from StringIO import StringIO
file1 = """
1 290 rs1345
2 450 rs5313
1 1120 rs4523
2 790 rs4325
"""
file2 = """
1 201 LDLR
2 714 APOA5
1 818 NOTCH5
1 514 TTN
"""
sio = StringIO(file1)
df1 = pd.read_table(sio, sep=" ", header=None)
df1.columns = ["a", "b", "c"]
sio = StringIO(file2)
df2 = pd.read_table(sio, sep=" ", header=None)
df2.columns = ["a", "b", "c"]
df = pd.merge(df2, df1, left_on="a", right_on="a", how="outer")
#query is intuitive
r = df.query("b_y-100 < b_x <b_y + 100")
print r[["a", "b_x", "c_x", "c_y"]]
输出:
a b_x c_x c_y
0 1 201 LDLR rs1345
7 2 714 APOA5 rs4325
pandas是进行此类表格数据操作的正确工具。