첫 번째 열을 기준으로 특정 수의 관측치가 있는 경우 행을 유지하는 방법은 무엇입니까?

첫 번째 열을 기준으로 특정 수의 관측치가 있는 경우 행을 유지하는 방법은 무엇입니까?

아래 예와 비슷한 파일이 있습니다. 첫 번째 열은 SNP ID입니다.

head data
2L:647803 1 2 44.31655 -12.2373
2L:647803 1 2 43.63717 -12.302
2L:647803 1 2 43.80007 -12.3451
2L:2602906 1 2 43.39748 -11.4894
2L:2602906 1 2 44.43951 -12.3093
2L:2602906 1 2 43.80007 -12.3451
2L:3146785 1 2 44.31655 -12.2373
2L:3146785 1 2 44.43951 -12.3093
2L:3146785 1 2 43.80007 -12.3451
2L:3771395 1 2 43.39748 -11.4894
2L:3771395 1 2 43.2661 -11.6803
2L:3945568 1 2 43.63717 -12.302
2L:3945568 1 2 43.39032 -11.6099

각 SNP( 2L:647803, 2L:2602906, 2L:3146785, ...)에 대해 3개의 행을 원합니다. 각 SNP에 대해 3개의 행이 없으면 해당 SNP를 삭제하고 싶습니다. 이것이 내가 원하는 출력입니다. ( 각 출력의 인스턴스가 두 개뿐이므로 제거되었습니다. 2L:37713952L:3945568

head desired
2L:647803 1 2 44.31655 -12.2373
2L:647803 1 2 43.63717 -12.302
2L:647803 1 2 43.80007 -12.3451
2L:2602906 1 2 43.39748 -11.4894
2L:2602906 1 2 44.43951 -12.3093
2L:2602906 1 2 43.80007 -12.3451
2L:3146785 1 2 44.31655 -12.2373
2L:3146785 1 2 44.43951 -12.3093
2L:3146785 1 2 43.80007 -12.3451

답변1

우아하지는 않지만 실용적입니다.

$ awk 'NR==FNR {a[$1]++; next} a[$1]==3' data data
2L:647803 1 2 44.31655 -12.2373
2L:647803 1 2 43.63717 -12.302
2L:647803 1 2 43.80007 -12.3451
2L:2602906 1 2 43.39748 -11.4894
2L:2602906 1 2 44.43951 -12.3093
2L:2602906 1 2 43.80007 -12.3451
2L:3146785 1 2 44.31655 -12.2373
2L:3146785 1 2 44.43951 -12.3093
2L:3146785 1 2 43.80007 -12.3451

답변2

밀러 사용(https://github.com/johnkerl/miller) 그리고 실행

mlr --nidx count-similar -g 1 then filter '$count==3' then cut -x -f count inputfile

당신은

2L:647803 1 2 44.31655 -12.2373
2L:647803 1 2 43.63717 -12.302
2L:647803 1 2 43.80007 -12.3451
2L:2602906 1 2 43.39748 -11.4894
2L:2602906 1 2 44.43951 -12.3093
2L:2602906 1 2 43.80007 -12.3451
2L:3146785 1 2 44.31655 -12.2373
2L:3146785 1 2 44.43951 -12.3093
2L:3146785 1 2 43.80007 -12.3451
  • mlr --nidx count-similar -g 1다양한 필드의 값 계산 1
  • then filter '$count==3'이 개수가 3인 행만 필터링합니다.
  • then cut -x -f count개수 열 삭제

답변3

여기에 또 다른 awk(그냥 awk) 해결책이 있습니다.

  • 입력이 "SNP id"로 정렬된다고 가정합니다. 즉, SNP id = 647인 모든 행이 함께 있게 됩니다.
  • 입력이 주문되었다고 가정하지 않습니다. 즉, SNP ID 647이 2602 이전 또는 이후에 나타날 수 있습니다.
  • 데이터는 한 번만 전달됩니다.
  • 3번 이상 나타나는 SNP ID에 대한 데이터는 출력되지 않습니다.
awk '
  {
    if ($1 == last) {
        count++
        if (count <= 3) line[count] = $0
    } else {
        if (count == 3) { print line[1]; print line[2]; print line[3]; }
        last = $1
        count = 1
        line[count] = $0
    }
  }
END {   if (count == 3) { print line[1]; print line[2]; print line[3]; } }
  '

첫 번째 필드/열( )에서 동일한 값을 가진 연속 행을 계산하고 $1동일한 값을 가진 행을 저장합니다. 새로운 값(또는 입력의 끝)을 발견하면 이전 값이 세 번 발생하면 저장된 줄을 인쇄합니다.

관련 정보