使用另一个具有核苷酸作为映射文件的文件将文件中的00、11、20中的snps更改为双等位字母等位基因

问题描述

我有一个raw.txt文件

FID IID FA  MO  SEX PHENO   SNP1    SNP2    SNP3    SNP4
1   1   0   0   1   1   20  00  20  11
1   2   0   0   1   1   11  00  20  20
1   3   0   0   1   1   11  20  11  20
1   4   0   0   1   1   00  11  11  20

snp.txt文件

1   SNP1    20  A   G
1   SNP2    45  T   C
1   SNP3    56  A   G
1   SNP4    80  C   G

我的输出文件应如下所示(在根据snp.txt中的第4列和第5列将数字从第7列转换为raw.txt中的字母之后):

FID IID FA  MO  SEX PHENO   SNP1    SNP2    SNP3    SNP4
1   1   0   0   1   1   AA  CC  AA  CG
1   2   0   0   1   1   AG  CC  AA  CC
1   3   0   0   1   1   AG  TT  AG  CC
1   4   0   0   1   1   GG  TC  AG  CC

snp.txt文件的第2列是从第7列(raw.txt)开始的raw.txt文件的头。 snp.txt文件的第4和第5列代表第2列的snps的次要和主要等位基因。我希望将SNP1,SNP2,SNP3和SNP4下的列以0,1,2格式使用第4列转换为ACGT格式和5作为地图。

raw.txt的SNP1,SNP2,SNP3和SNP4列代表未成年人等位基因的0.1或2个副本(snp.txt文件的第4列)。第5列是主要的等位基因。如果如raw.txt中所示,SNP1是20,则有2个次要等位基因副本,根据snp.txt,它是A。因此20应该改为AA(20中的2是次要等位基因A的计数)。 SNP1 11表示存在1个次要等位基因副本。因此11应该是AG。 SNP1 00表示没有次要等位基因,只有主要等位基因。因此00应该是snp.txt文件的GG(第5列中的字母的2个副本)。

实际上,我有超过65,000个snps,这意味着raw.txt文件有很多列。我有下面的代码(我在stackoverflow上找到的代码我做了一些编辑:

awk 'NR==FNR {a[$2,20]=$4$4; a[$2,11]=$4$5; a[$2,"00"]=$5$5; next} $7~/^[0-2]/ {
     $7=a["SNP1",$7]; $8=a["SNP2",$8];9=a["SNP3",$9];$10=a["SNP4",$10]}1'
snp.txt raw.txt > output.txt

如果raw.txt文件只有4个snps,这就是我想要的。当我有超过65,000个snps时,我不知道如何通过raw.txt的第7列中的字段进行此循环。我想要一个代码(最好是awk语言),该代码可以遍历raw.txt的许多列,以将00、11、20格式的snps更改为双等位字母格式。谢谢。

解决方法

您的awk很好!这是针对可变数量的snps的方法。

> cat tst.awk 
NR==FNR {
    snp[$2 "20"] = $4 $4
    snp[$2 "11"] = $4 $5
    snp[$2 "00"] = $5 $5
    next
}

FNR==1 { # read the columns/snps
    for (i=7;i<=NF;i++) col[i] = $i
    print
    next
}

{
    for (i=7;i<=NF;i++) $i = snp[col[i] $i]
    print
}

用法:

> awk -f tst.awk snp.txt raw.txt 
FID IID FA  MO  SEX PHENO   SNP1    SNP2    SNP3    SNP4
1 1 0 0 1 1 AA CC AA CG
1 2 0 0 1 1 AG CC AA CC
1 3 0 0 1 1 AG TT AG CC
1 4 0 0 1 1 GG TC AG CC

修改之处在于,我们读取了标头并保存了snps,稍后再将它们用于映射。这两个动作都是通过典型的for循环完成的,从我们想要的列到最后一列(NF),剩下的就是您已经在做的事情,除了语法更清晰以外。