我的任务是修改蒙面基因型,我必须掩盖(隐藏)2%的基因型。
我这样做的文件看起来像这样(genotype.dat):
M rs4911642 M rs9604821 M rs9605903 M rs5746647 M rs5747968 M rs5747999 M rs2070501 M rs11089263 M rs2096537
并掩饰它,我只需将M改为S2。
然而,我必须对5505行中的110(2%)执行此操作,因此我使用随机数生成器的策略(在1到5505之间生成110个数字,然后手动更改相应的行号' s M到S2花了差不多一个小时......(我知道,并不是非常复杂)。
我考虑将数字保存在一个单独的文件(maskedlines.txt)中,然后告诉awk用S2替换该行号中的第一个字符,但我找不到任何可调节的例子来执行此操作。
无论如何,任何有关如何解决这个问题的建议都将深受赞赏。
答案 0 :(得分:1)
awk 'NR==FNR{a[$1]=1;next;} a[FNR]{$1="S2"} 1' maskedlines.txt genotype.dat
总而言之,我们首先将maskedlines.txt
读入关联数组a
。假设该文件每行有一个数字,并且该数字的a
设置为1。然后我们读入genotype.dat
。如果该行号的a
为1,我们会将第一个字段更改为S2
以屏蔽它。然后打印该行,无论是否改变。
详细说明:
NR==FNR{a[$1]=1;next;}
在awk中,FNR
是到目前为止从当前文件读取的记录(行)数,NR
是到目前为止读取的总行数。所以,当NR==FNR
时,我们正在读取第一个文件(maskedlines.txt)。此文件包含要屏蔽的genotype.dat中的行号。对于这些行号中的每一行,我们将a
设置为1.然后我们跳过其余命令并跳转到next
行。
a[FNR]{$1="S2"}
如果我们到这里,我们正在处理第二个文件:genotype.dat。对于此文件中的每一行,我们会检查FNR
中是否提及其行号maskedlines.txt
。如果是,我们将第一个字段设置为S2
以掩盖此行。
1
这是打印当前行的awck简洁速记。
答案 1 :(得分:1)
这是一个简单的方法,如果你有shuf
(它在Gnu coreutils中,所以如果你有Linux,你几乎肯定有它):
sed "$(printf '%ds/M/S2/;' $(shuf -n110 -i1-5505 | sort -n))" \
genotype.dat > genotype.masked
更复杂的版本不依赖于知道你想要掩盖5505行中的110行;您可以使用lines=$(wc -l < genotype.dat)
轻松提取行数,然后从中计算百分比。
shuf
用于生成随机的行样本,通常来自文件; -i1-5505
选项意味着使用1到5505之间的整数,-n110
表示生成110的随机样本(不重复)。在使用printf
创建sed
编辑脚本之前,我对其效率进行了排序。