![크기가 다른 여러 파일의 열을 비교하고 일치하지 않는 값을 NA로 바꿉니다.](https://linux55.com/image/112519/%ED%81%AC%EA%B8%B0%EA%B0%80%20%EB%8B%A4%EB%A5%B8%20%EC%97%AC%EB%9F%AC%20%ED%8C%8C%EC%9D%BC%EC%9D%98%20%EC%97%B4%EC%9D%84%20%EB%B9%84%EA%B5%90%ED%95%98%EA%B3%A0%20%EC%9D%BC%EC%B9%98%ED%95%98%EC%A7%80%20%EC%95%8A%EB%8A%94%20%EA%B0%92%EC%9D%84%20NA%EB%A1%9C%20%EB%B0%94%EA%BF%89%EB%8B%88%EB%8B%A4..png)
세 개의 데이터 프레임이 있습니다.
데이터 프레임 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
,df3
두df1
번째, 세 번째, 첫 번째데이터 프레임별도의 파일FILENAME
- 내장 변수는 현재 처리 중인 파일의 이름을 가리킵니다.ARGV
- awk 스크립트에 전달된 모든 인수를 가리키는 내장 변수입니다. 그것은ARGV[1]
포함df2
FILENAME == ARGV[1] && NR>1
- 첫 번째 파일이 발견됩니다(즉,df2
두 번째 줄부터 시작).df2[$2,$3,$4]
- 다음에서 키 값을 가져옵니다.데이터 프레임 2"를 배열 키로df2
FILENAME == ARGV[2] && FNR>1
df3
- 두 번째 줄부터 시작하는 두 번째 파일을 발견했습니다(예:)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개의 요소가 있음) 동안 첫 번째 데이터 프레임의 내용으로 각 행을 인쇄하고 현재 두 번째 데이터 프레임의 두 번째/세 번째 프레임에 해당하는 배열 요소/세 번째 필드가 있는지 확인합니다.