使用 join/awk 在一个表中查找值并将其输出到另一个表中

使用 join/awk 在一个表中查找值并将其输出到另一个表中

表 1(制表符分隔):

NC_000001.11 1243 A T 0.14 
NC_000005.11 1432 G C 0.0006 
NC_000012.12 1284 A T 0.93428 
NC_000021.9 9824 T C 0.9

查找表(制表符分隔)- 这实际上很大,gzip 后大约有 6G:

 NC_000001.11 1243 rs73647921 A   T  
 NC_000005.11 1432 rs75444    G   C
 NC_000012.12 1284 rs754723 A T  
 NC_000021.9 9824 rs865545  T C 

我希望输出匹配表 1 的前 4 列,它们对应于查找表的第 1/2/4/5 列;将表1转化为:

MarkerName P-Value
rs73647921 0.14
rs75444    0.0006
rs754723 0.93428 
rs865545  0.9

我认为我需要按照以下方式使用 join:

join -t, -a 1 -a 2 -o0,1.5,2.3 -e ' -' file1 file2

但这似乎不起作用。我怎样才能使用 gzip 压缩文件?

答案1

使用 awk (和 bash)你可以写

awk '
    BEGIN {FS = OFS = "\t"}
    NR == FNR {pvalue[$1,$2,$3,$4] = $5; next}
    FNR == 1 {print "MarkerName", "P-Value"}
    { key = $1 SUBSEP $2 SUBSEP $4 SUBSEP $5
      sub(/\r$/, "", key)
    }
    key in pvalue {print $3, pvalue[key]}
' table1.tsv <(zcat lookup.tsv.gz)

awk 使用 SUBSEP 变量来连接数组的逗号分隔索引。

zcat 周围的最后一点语法是 bash流程替代

对于多字段连接条件,join处理起来可能会很痛苦。如果文件未排序,它也会抱怨。

答案2

你有没有尝试过 .. ?

join -o 2.3,1.5 f1 <(zcat f2.gz )

默认情况下join使用第一个字段。 (并且-1 x -2 x相当于-j x,并且-j 1相当于" "

我假设

  • 文件已排序,
  • 键仅是第一个字段。

对所有字段进行排序

join -o 2.2,1.2 \
    <(awk '{printf "%s %s\n",$1 $2 $3 $4,$5}' f1) \
    <(zcat f2.gz| awk '{printf "%s %s\n",$1 $2 $4 $5,$3}' )

在哪里

  • 使用两个awk管道join可能不是一个好主意(尽管与awk唯一的解决方案相比,这可能会节省内存),
  • awk命令从相关字段构建索引,
  • zcat用于解压缩,
  • 这让0问题悬而未决。

相关内容