여러 행과 열이 있는 파일이 있습니다. 숫자 2가 x회 이상 나타나는 열을 선택하고 싶습니다.
내 탭으로 구분된 파일은 다음과 같습니다.
Individuals M1 M2 M3
Ind1 0 0 2
Ind2 0 2 2
Ind3 2 2 2
이 만화 예에서는 숫자 2가 두 번 이상 나타나는 열을 원한다고 가정해 보겠습니다. 내 결과는 다음과 같습니다
Individuals M2 M3
Ind1 0 2
Ind2 2 2
Ind3 2 2
R로는 쉽지만, 파일이 너무 크기 때문에 시간이 오래 걸리기 때문에 awk 등을 이용해서 하고 싶습니다. 이것을 달성하는 방법을 말해 줄 수 있습니까?
답변1
BEGIN { OFS = FS = "\t" }
FNR == NR {
for (i = 2; i <= NF; ++i)
if ($i == 2) ++c[i]
next
}
{
a[nf=1] = $1
for (i = 2; i <= NF; ++i)
if (c[i] >= t) a[++nf] = $i
$0 = ""
for (i = 1; i <= nf; ++i)
$i = a[i]
print
}
프로그램 awk
은 각 열에서 해당 값의 발생 횟수를 계산 2
하고 이러한 수를 배열 c
(데이터의 각 열에 대해 하나의 요소)에 저장합니다. 입력 파일(블록)을 처음 읽을 때 이 작업을 수행합니다 FNR == NR
.
입력 파일을 두 번째로 읽으면 이 개수를 사용하여 입력의 적절한 열을 a
각 행에 대해 읽은 배열로 전송합니다. 변수 값은 t
열을 포함해야 하는지 여부를 결정하는 임계값으로 사용됩니다. 이것은 for
마지막 코드 블록의 첫 번째 루프입니다.
그런 다음 이 배열에서 새 데이터 레코드를 생성하고 인쇄합니다.
awk
테스트해 보세요( 두 번 전달할 수 있도록 입력 파일이 명령줄에 두 번 제공된다는 점에 유의하세요 ).
$ cat file
Individuals M1 M2 M3
Ind1 0 0 2
Ind2 0 2 2
Ind3 2 2 2
$ awk -v t=1 -f script.awk file file
Individuals M1 M2 M3
Ind1 0 0 2
Ind2 0 2 2
Ind3 2 2 2
$ awk -v t=2 -f script.awk file file
Individuals M2 M3
Ind1 0 2
Ind2 2 2
Ind3 2 2
$ awk -v t=3 -f script.awk file file
Individuals M3
Ind1 2
Ind2 2
Ind3 2
$ awk -v t=4 -f script.awk file file
Individuals
Ind1
Ind2
Ind3
답변2
이것이 빠른지 확실하지 않습니다.
awk -v value=0 '
NR==FNR{for(i=2;i<=NF;i++){if($i==value){s[i]++}}}
NR!=FNR {
printf "%s"OFS,$1
for (i=2;i<=NF;i++){if(s[i]>1)last=i}
for (i=2;i<=NF;i++){
if(s[i]>1){
if (i==last)printf "%s\n",$i
else printf "%s"OFS,$i}
}
}
' file file
OFS
탭( BEGIN{OFS="\t"}
.) 으로 설정할 수도 있습니다 .