1

我有一个 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 列是文件 raw.txt 从第 7 列 (raw.txt) 开始的标题。文件 snp.txt 的第 4 列和第 5 列代表第 2 列中 snps 的次要和主要等位基因。我希望使用第 4 列将 0、1、2 格式的 SNP1、SNP2、SNP3 和 SNP4 下的列转换为 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 更改为双等位字母格式。谢谢你。

4

1 回答 1

2

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

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

于 2020-09-07T22:06:52.560 回答