如何在Terminal Linux中将列转换为行?但更复杂......以下是我的数据示例:
SNP_Name ID_Animal Allele Chr Position
rs01 215 AB 1 100
rs02 215 AA 2 200
rs03 215 BA 3 300
rs04 215 AA 4 400
rs01 300 AB 1 100
rs02 300 BB 2 200
rs03 300 AA 3 300
rs04 300 AB 4 400
rs01 666 BB 1 100
rs02 666 AA 2 200
rs03 666 AB 3 300
rs04 666 AB 4 400
我想将其转换为以下内容:
SNP_Name Chr Position 215(ID_animal) 300(ID_Animal) 666(ID_Animal)
rs01 1 100 AB AB BB
rs02 2 200 AA BB AA
rs03 3 300 BA AA AB
rs04 4 400 AA AB AB
行ID_animal
在具有相应等位基因的列中发生变化。我是怎么做到的
但是每ID_animal
我将重复55,000次。所以,我希望列只有55,000行和(动物number
+ SNP_Name
+ Chr
+ Position
)列。
谢谢。
答案 0 :(得分:1)
这里的问题是数据量,我不想提供一个解决方案,将所有内容读入内存然后输出。
为此,我想依次解析并输出每个SNP(rs
数字)的数据,而不是每个动物。但数据是以错误的顺序提供给我们的(按动物分类)。
因此,我们需要做的第一件事是按SNP(第一列)对数据进行排序。我还将同时删除标题行,因为数据转换不需要它。
我假设数据存储在文件data.in
中:
$ sed '1d' data.in | sort -o data.tmp
我们现在有:
$ cat data.tmp
rs01 215 AB 1 100
rs01 300 AB 1 100
rs01 666 BB 1 100
rs02 215 AA 2 200
rs02 300 BB 2 200
rs02 666 AA 2 200
rs03 215 BA 3 300
rs03 300 AA 3 300
rs03 666 AB 3 300
rs04 215 AA 4 400
rs04 300 AB 4 400
rs04 666 AB 4 400
然后我运行以下命令来产生结果:
$ awk -f script.awk data.tmp >data.new
awk
脚本很长,因此将它放在自己的脚本文件中而不是“单行”中是有意义的:
FNR == 1 {
# at first line of input
rsid = $1;
chr = $4;
pos = $5;
c = 0;
aid[c] = $2; # animal ID
all[c++] = $3; # allele
do_header = 1; # output header when done parsing this SNP
next;
}
rsid == $1 {
# still reading animal ID/allele for this SNP
aid[c] = $2;
all[c++] = $3;
next;
}
{
if (do_header) {
# output header
printf("SNP_name\tChr\tPosition\t");
for (c in aid) {
printf("%d\t", aid[c]);
}
printf("\n");
do_header = 0;
}
# output line with data from previous SNP
printf("%s\t%d\t%d\t", rsid, chr, pos);
for (c in all) {
printf("%s\t", all[c]);
}
printf("\n");
# store data for this SNP
rsid = $1;
chr = $4;
pos = $5;
c = 0;
aid[c] = $2;
all[c++] = $3;
}
END {
# output line for last SNP
printf("%s\t%d\t%d\t", rsid, chr, pos);
for (c in all) {
printf("%s\t", all[c]);
}
printf("\n");
}
对于给定的输入,这会生成带有以下内容的制表符分隔文件data.new
:
SNP_name Chr Position 215 300 666
rs01 1 100 AB AB BB
rs02 2 200 AA BB AA
rs03 3 300 BA AA AB
rs04 4 400 AA AB AB
注意:此要求对所有动物进行基因分型以获得完全相同的SNP。每个SNP都需要相同的动物ID。没有例外。