단계별로

단계별로

2개의 파일이 있습니다. 파일 1의 열 1은 파일 2의 열 2로 바뀌어야 하며, 파일 1의 열 2,3,4-5 또는 5-4(교차 일치)는 열 1,4,5와 일치합니다. -6 또는 파일 2의 6-5.

파일 1

SNP     Chr     Pos     EA      NEA     EAF     Beta    SE      Pvalue  Neff
1:79137     1       79137       A       T       0.25    -0.026  0.0073  4.0e-04 231420
1:79033      1       79033        A       G       0.0047  -0.038  0.056   4.9e-01 225429
1:118630     1       118630       C       T       0.99    -0.033  0.055   5.5e-01 226311
1:533179     1       533179       A       G       1       -0.098  0.19    6.1e-01 185906

파일 2

1       1:79033_A_G     0       79033   A       G
1       1:79137_A_T     0       79137   T       A
1       1:118630_C_T    0       118630  T       C
1       1:533179_A_G    0       533179  G       A

다음과 같은 출력이 필요합니다.

SNP     Chr     Pos     EA      NEA     EAF     Beta    SE      Pvalue  Neff
    1:79137_A_T     1       79137       A       T       0.25    -0.026  0.0073  4.0e-04 231420
    1:79033_A_G      1       79033        A       G       0.0047  -0.038  0.056   4.9e-01 225429
    1:118630_C_T     1       118630       C       T       0.99    -0.033  0.055   5.5e-01 226311
    1:533179_A_G     1       533179       A       G       1       -0.098  0.19    6.1e-01 185906

파일에 정확한 줄 수가 없으며 파일이 탭으로 구분되지 않습니다. 아래 코드를 시도했지만 작동하지 않습니다. 코드를 수정해 주실 수 있나요?

awk 'NR==FNR{chr[$1]=$1;snp[$2]=$2;pos[$4]=$4;a1[$5]=$5;a2[$6]=$6;next} ($1 in chr)&&($4 in pos)&& ((($5 in a1) && ($6 in a2)) || (($6 in a1) && ($5 in a2))) {$2==snp[$2]}' file 2 file1

편집 1:

다음 Perl 코드는 일부 오류를 일으키고 약 20,000개의 중복 행을 생성합니다.

파일 1

SNP     Chr     Pos     EA      NEA     EAF     Beta    SE      Pvalue  Neff
7:10100610      7       10100610        A       G       0.0002  0.13    0.58    8.2e-01 120658
7:10100610      7       10100610        C       G       0.0013  0.1     0.13    4.4e-01 139170
10:1006107      10      1006107 C       G       1       -0.11   0.42    7.9e-01 152016

파일 2

7       7:10100610_G_A  0       10100610        A       G
7       7:10100610_G_C  0       10100610        C       G
10      10:1006107_C_G  0       1006107 G       C

다음 줄의 예상 출력은 다음과 같습니다.

7:10100610_G_A      7       10100610        A       G       0.0002  0.13    0.58    8.2e-01 120658
7:10100610_G_C      7       10100610        C       G       0.0013  0.1     0.13    4.4e-01 139170
10:1006107_C_G      10      1006107 C       G       1       -0.11   0.42    7.9e-01 152016

그러나 Perl 코드는 출력을 제공합니다.

7:10100610_G_A  7       10100610        A       G       0.0002  0.13    0.58    8.2e-01 120658
10:1006107_C_G  7       10100610        C       G       0.0013  0.1     0.13    4.4e-01 139170
10:1006107_C_G  10      1006107 C       G       1       -0.11   0.42    7.9e-01 152016

답변1

join명령은 여러 파일에서 일치하는 줄을 연결하는 작업을 수행합니다. 그러나 입력 파일에 대한 몇 가지 요구 사항이 있으므로 프로세스 중에 몇 가지 임시 파일과 몇 가지 추가 필드를 만들어야 합니다.

awk '{printf $2" "$3" "$4" "$5"%"$1"%"; $1="";print $0 "%" NR }' < file1 | sort > 1.tmp
awk '{print $1" "$4" "$5" "$6"%"$2} $5 != $6 {print $1" "$4" "$6" "$5"%"$2}' < file2 | sort > 2.tmp

join -a 1 -t % -o 1.4 2.2 1.2 1.3  1.tmp 2.tmp | sort -t % -n | awk -F %  '!$2{$2=$3}{print $2" "$4}'

단계별로

첫 번째 파일을 전처리합니다.

awk '{printf $2" "$3" "$4" "$5"%"$1"%"; $1="";print $0 "%" NR }''

출력 예:

1 118630 C T%1:118630% 1 118630 C T 0.99 -0.033 0.055 5.5e-01 226311%4

이 4개 필드는 %다음과 같이 구분됩니다.

  • 일치해야 하는 "키"(입력 필드 2-5)
  • 원래 첫 번째 열(일치하는 항목이 없는 경우 필수)
  • 원래 줄의 나머지 부분
  • 원래 줄 번호(나중에 파일 순서를 복원할 수 있도록 sort)

이 출력은 입력을 정렬해야 하므로 sort임시 파일로 파이프됩니다 .join

두 번째 파일의 경우:

awk '{print $1" "$4" "$5" "$6"%"$2} $5 != $6 {print $1" "$4" "$6" "$5"%"$2}'

출력 예:

1 118630 C T%1:118630_C_T
1 118630 T C%1:118630_C_T

필드 5와 6이 일치하도록 지정하면 두 번째 줄이 인쇄되고 서로 교체됩니다(동일하지 않은 경우). 여기서 -로 구분된 필드 %는 다음과 같습니다.

  • "키"와 일치해야 함
  • 2열

이번에도 출력이 sort다른 임시 파일로 파이프됩니다.

그런 다음 주요 "참여" 단계가 옵니다.

join -a 1 -t % -o 1.4 2.2 1.2 1.3  1.tmp 2.tmp

두 번째 그룹에 일치하는 항목이 없을 때 -a 1첫 번째 그룹의 행을 유지하도록 지시합니다 . 구분 기호를 (공백 대신)로 설정합니다. 이 매개변수는 다음 4개의 출력 필드를 생성합니다.join-t %%-o

  • 파일 1, 열 4: 줄 번호
  • 파일 2, 열 2: 대체 위치 file2(일치하는 항목이 없으면 비어 있음)
  • 파일 1, 열 2: 원본 열 1file1
  • 파일 1, 열 3: 행의 나머지 부분은file1

예제 출력 라인:

4%1:118630_C_T%1:118630% 1 118630 C T 0.99 -0.033 0.055 5.5e-01 226311

그런 다음 sort원래 파일 순서를 복원할 수 있습니다(숫자 정렬, 필드 구분 기호 %).

sort -t % -n

마지막으로 awk"교체" 필드가 비어 있는지 확인하고(일치하는 항목이 없기 때문에) 비어 있는 경우 원래 열1을 ​​사용합니다. 또한 줄 번호와 모든 을 버립니다 %.

awk -F % '!$2{$2=$3}{print $2" "$4}'

최종 출력 라인:

1:118630_C_T  1 118630 C T 0.99 -0.033 0.055 5.5e-01 226311

답변2

저는 Perl에서 이것을 할 것입니다. 왜냐면 Perl에는 and를 같은 것으로 sort쉽게 처리할 수 있는 기능이 있기 때문입니다. 예를 들어(모든 예제 파일의 출력을 결합하여 표시):A TT A

$ perl -lane 'if(!$k){$name{join("","chr".$F[0],$F[3],sort($F[4],$F[5]))}=$F[1]; }else{$var=join("", "chr".$F[1],$F[2],sort($F[3],$F[4])); $F[0]=$name{$var} if $name{$var};print join "\t", @F; } $k++ if eof' file2 file1
SNP Chr Pos EA  NEA EAF Beta    SE  Pvalue  Neff
7:10100610_G_A  7   10100610    A   G   0.0002  0.13    0.58    8.2e-01 120658
7:10100610_G_C  7   10100610    C   G   0.0013  0.1 0.13    4.4e-01 139170
10:1006107_C_G  10  1006107 C   G   1   -0.11   0.42    7.9e-01 152016
1:79137_A_T 1   79137   A   T   0.25    -0.026  0.0073  4.0e-04 231420
1:79033_A_G 1   79033   A   G   0.0047  -0.038  0.056   4.9e-01 225429
1:118630_C_T    1   118630  C   T   0.99    -0.033  0.055   5.5e-01 226311
1:533179_A_G    1   533179  A   G   1   -0.098  0.19    6.1e-01 185906

또는 약간 더 명확합니다.

$ perl -lane 'if(!$k){
                $name{join("","chr".$F[0],$F[3],sort($F[4],$F[5]))}=$F[1]; 
              }
              else{
                $var=join("", "chr".$F[1],$F[2],sort($F[3],$F[4])); 
                $F[0]=$name{$var} if $name{$var};
                print join "\t", @F; 
             } 
            $k++ if eof' file2 file1
SNP Chr Pos EA  NEA EAF Beta    SE  Pvalue  Neff
7:10100610_G_A  7   10100610    A   G   0.0002  0.13    0.58    8.2e-01 120658
7:10100610_G_C  7   10100610    C   G   0.0013  0.1 0.13    4.4e-01 139170
10:1006107_C_G  10  1006107 C   G   1   -0.11   0.42    7.9e-01 152016
1:79137_A_T 1   79137   A   T   0.25    -0.026  0.0073  4.0e-04 231420
1:79033_A_G 1   79033   A   G   0.0047  -0.038  0.056   4.9e-01 225429

설명하다

  • perl -lane: 이는 -aPerl을 awk처럼 동작하게 하며 자동으로 입력을 공백의 배열로 분할합니다 @F. Perl 배열은 첫 번째 필드 로 시작 0하므로 두 번째 필드가 됩니다. 필드 N은 입니다 . Perl이 인수를 텍스트 파일로 읽고 주어진 스크립트를 각 행 에 적용하도록 합니다 . 각 입력 줄에서 후행 개행 문자를 제거하고 각 호출에 개행 문자를 추가하기 만 하면 됩니다 .$F[0]$F[1]$F[N-1]-n-e-lprint

  • $k++ if eof$k: 파일의 끝( eof)에 도달하면 변수가 1 증가합니다. 그런 다음 if(!$k)($k가 정의되지 않은 경우) NR==FNRawk에서 동등한 것으로 사용할 수 있습니다 .

  • if(!$k){$name{join("","chr".$F[0],$F[3],sort($F[4],$F[5]))}=$F [1];} : if this is the first file,file2 , join fields 1, 4, and the sorted fields 5 and 6, into a string and use that string as the key in the hash (associative array)name . Then, save the variant's name from file2 as the value associated with that key. The sorting lets us treatAT andTA as equivalent. I use"chr".$F[0] to deal with cases like1 123 and11 23`, 여기서 염색체와 위치를 연결하면 염색체가 실제로 다르더라도 동일한 번호가 제공됩니다.

  • else{: 지금 두 번째 파일을 읽고 있다면 file1.

  • $var=join("", $F[1],$F[2],sort($F[3],$F[4]));: 빌드 키. 이번에는 필드 2, 3을 사용하고 4와 5를 정렬합니다.
  • $F[0]=$name{$var} if $name{$var};name: 키에 값이 있으면 첫 번째 필드를 해시에 저장된 값으로 설정합니다. 헤더 나 존재하지만 존재하지 않는 다른 변형을 if변경하지 않도록 해야 합니다 .file1file2
  • print join "\t", @F;:위에서 변경한 내용을 포함하여 필드를 인쇄합니다.

관련 정보