나는 다음과 같은 데이터를 가지고 있습니다. 각 SNP에 대해 서로 다른 베타를 사용하여 5번 반복해야 합니다. 그런데 SNP rs11704961의 경우 2번만 반복되므로 5번 미만으로 반복되는 SNP 행을 제거하고 싶습니다. 사용해 보았지만 sort -k 1 | uniq -c
중복 여부를 확인하기 위해 첫 번째 열이 아닌 전체 행을 고려합니다.
SNP R K BETA
rs767249 1 1 0.1065
rs767249 1 2 -0.007243
rs767249 1 3 0.02771
rs767249 1 4 -0.008233
rs767249 1 5 0.05073
rs11704961 2 1 0.2245
rs11704961 2 2 0.009203
rs1041894 3 1 0.1238
rs1041894 3 2 0.002522
rs1041894 3 3 0.01175
rs1041894 3 4 -0.01122
rs1041894 3 5 -0.009195
답변1
사용 awk
:
$ cat snp.awk
NR == 1 { # header line
print $0
}
NR > 1 { # data line
snp = $1;
retain[snp][NR] = $0;
counts[snp]++;
}
END {
for (snp in retain) {
if (counts[snp] == 5) {
for (i in retain[snp]) {
print retain[snp][i];
}
}
}
}
$ awk -f snp.awk snp.dat
SNP R K BETA
rs1041894 3 1 0.1238
rs1041894 3 2 0.002522
rs1041894 3 3 0.01175
rs1041894 3 4 -0.01122
rs1041894 3 5 -0.009195
rs767249 1 1 0.1065
rs767249 1 2 -0.007243
rs767249 1 3 0.02771
rs767249 1 4 -0.008233
rs767249 1 5 0.05073
그러나 awk
배열은 삽입 순서를 유지하지 않으므로 이 경우 출력은 입력 순서와 동일하지 않습니다.
답변2
사용밀러- 와 유사 awk
하지만 기본적으로 헤더 행을 처리합니다.
$ cat snp.mlr
@records[$SNP][NR] = $*; # retain records
@counts[$SNP] += 1;
end { # conditionally emit
for (snp in @records) {
if (@counts[snp] == 5) {
emit @records[snp];
}
}
}
$ mlr --csvlite --fs space put -q -f snp.mlr snp.dat
SNP R K BETA
rs767249 1 1 0.1065
rs767249 1 2 -0.007243
rs767249 1 3 0.02771
rs767249 1 4 -0.008233
rs767249 1 5 0.05073
rs1041894 3 1 0.1238
rs1041894 3 2 0.002522
rs1041894 3 3 0.01175
rs1041894 3 4 -0.01122
rs1041894 3 5 -0.009195
참고로 이는최신 버전 4.5.0.