크기가 다른 여러 파일의 열을 비교하고 일치하지 않는 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

첫 번째 데이터 프레임의 4번째 열에 따라 두 번째 및 세 번째 데이터 프레임의 4번째 열과 관련하여 일치 또는 불일치가 보고되는 최종 데이터 프레임을 얻고 싶습니다. 새 데이터 프레임에서 일치하는 항목이 있으면 동일한 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, df3그리고 df1당신의 두 번째, 세 번째, 첫 번째입니다데이터프레임파일을 각각

  • 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에 4번째 열이 모두 채워져 있고 IOW가 있다고 가정하면 누락된 열은 없습니다.
  • Perlline-read-in+autosplit 모드에서 호출합니다 :perl -lane
  • 세 번째 프레임을 읽는 동안 @ARGV에는 2개의 요소가 있고, 두 번째 프레임을 읽는 동안에는 1개의 요소가 있고, 세 번째 프레임에는 0개의 요소가 있습니다.
  • %h우리는 키가 두 번째 + 세 번째 필드 $F[1],$F[2]이고 값이 익명 배열 참조인 해시를 채웁니다 $h{...}[...].
  • 첫 번째 데이터 프레임(요소가 0개인 @ARGV) 동안 첫 번째 데이터 프레임의 내용으로 각 줄을 인쇄하고 해당 현재 두 번째 프레임의 두 번째/세 번째 프레임에 대해 배열 요소가 존재하는지 여부를 확인합니다. /3번째 필드.

관련 정보