크기가 다른 여러 파일의 열을 비교하고 일치하지 않는 값을 NA로 바꿉니다.

크기가 다른 여러 파일의 열을 비교하고 일치하지 않는 값을 NA로 바꿉니다.

세 개의 데이터 프레임이 있습니다.

데이터 프레임 1

chr start end Id chr1 1 400 SN_1 chr1 401 800 SN_2 chr1 801 1200 SN_3 chr1 1201 1600 SN_4 chr1 1601 2000 SN_5 chr1 2001 2400 SN_6 chr1 2401 2800 SN_7

데이터 프레임 2

chr start end Id chr1 401 800 SN_2 chr1 801 1200 SN_3 chr1 1201 1600 SN_4

데이터 프레임 3

chr start end Id chr1 1201 1600 SN_4 chr1 1601 2000 SN_5 chr1 2001 2400 SN_6

첫 번째 데이터 프레임의 네 번째 열을 기반으로 두 번째 및 세 번째 데이터 프레임의 네 번째 열을 기준으로 일치 또는 불일치가 보고되는 최종 데이터 프레임을 얻고 싶습니다. 새 데이터 프레임에서 일치하는 항목이 있으면 동일한 ID가 보고되지만 일치하는 항목이 있는 경우 ID 이름은 NA로 대체됩니다. 어쩌면 입력과 출력을 작성하는 것이 이해하기 더 쉬울 수도 있습니다. 이 같은:

원하는 출력:

chr start end Id Id Id chr1 1 400 SN_1 NA NA chr1 401 800 SN_2 SN_2 NA chr1 801 1200 SN_3 SN_3 NA chr1 1201 1600 SN_4 SN_4 SN_4 chr1 1601 2000 SN_5 NA SN_5 chr1 2001 2400 SN_6 NA SN_6 chr1 2401 2800 SN_7 NA NA

unix 명령에서 Join을 사용해 보았지만 크기가 다른 데이터 프레임을 비교할 수 없습니다. 어떤 아이디어라도 크게 감사하겠습니다.

답변1

해결책:

awk 'FILENAME == ARGV[1] && NR>1{ df2[$2,$3,$4] }
     FILENAME == ARGV[2] && FNR>1{ df3[$2,$3,$4] }
     FILENAME == ARGV[3]{ if(FNR == 1) { printf("%s\t%s\t%s\n",$0,$NF,$NF) } 
     else { printf("%s\t%s\t%s\n",$0, (($2,$3,$4) in df2)? $NF :"NA",(($2,$3,$4) in df3)? $NF :"NA")} 
}' df2 df3 df1 | column -t

산출:

chr   start  end   Id    Id    Id
chr1  1      400   SN_1  NA    NA
chr1  401    800   SN_2  SN_2  NA
chr1  801    1200  SN_3  SN_3  NA
chr1  1201   1600  SN_4  SN_4  SN_4
chr1  1601   2000  SN_5  NA    SN_5
chr1  2001   2400  SN_6  NA    SN_6
chr1  2401   2800  SN_7  NA    NA

  • df2, df3df1번째, 세 번째, 첫 번째데이터 프레임별도의 파일

  • FILENAME- 내장 변수는 현재 처리 중인 파일의 이름을 가리킵니다.

  • ARGV- awk 스크립트에 전달된 모든 인수를 가리키는 내장 변수입니다. 그것은 ARGV[1]포함df2

  • FILENAME == ARGV[1] && NR>1- 첫 번째 파일이 발견됩니다(즉, df2두 번째 줄부터 시작).

    • df2[$2,$3,$4]- 다음에서 키 값을 가져옵니다.데이터 프레임 2"를 배열 키로df2
  • FILENAME == ARGV[2] && FNR>1df3- 두 번째 줄부터 시작하는 두 번째 파일을 발견했습니다(예:)

    • df3[$2,$3,$4]- 다음에서 키 값을 가져옵니다.데이터 프레임 3"를 배열 키로df3
  • FILENAME == ARGV[3]- 세 번째 파일(예 df1: )을 발견했습니다.데이터 프레임

답변2

perl -lane '$,="\t";
   !@ARGV and $. == 1 and print($_, qw/Id/x2),next;
   $h{$F[1],$F[2]}->[@ARGV] = $F[3];
   !@ARGV and print $_, map { $h{$F[1],$F[2]}->[$_] // q/NA/ } 1..2;
   $. = 0 if eof;
' file3 file2 file1

결과

chr    start   end     Id       Id      Id
 chr1   1       400     SN_1    NA      NA
 chr1   401     800     SN_2    SN_2    NA
 chr1   801     1200    SN_3    SN_3    NA
 chr1   1201    1600    SN_4    SN_4    SN_4
 chr1   1601    2000    SN_5    NA      SN_5
 chr1   2001    2400    SN_6    NA      SN_6
 chr1   2401    2800    SN_7    NA      NA

작동 원리

  • 입력 순서는 dataframe3, dataframe2, dataframe1입니다.
  • dataframe1에 네 번째 열인 IOW가 모두 채워져 있다고 가정하면 누락된 항목이 없습니다.
  • 우리는 Perl이것을 줄 읽기 + 자동 분할 모드라고 부릅니다:perl -lane
  • 프레임 3을 읽는 동안 @ARGV에는 2개의 요소가 있고, 프레임 2를 읽는 동안 1개의 요소를 읽었으며, 프레임 3을 읽는 동안 0개의 요소를 읽었습니다.
  • %h키가 2+3번째 필드이고 $F[1],$F[2]값이 익명 배열 참조인 해시를 채웁니다 . 따라서 이름은 입니다 $h{...}[...].
  • 첫 번째 데이터 프레임(@ARGV에는 0개의 요소가 있음) 동안 첫 번째 데이터 프레임의 내용으로 각 행을 인쇄하고 현재 두 번째 데이터 프레임의 두 번째/세 번째 프레임에 해당하는 배열 요소/세 번째 필드가 있는지 확인합니다.

관련 정보