2017-08-03 4 views
0

2つのファイルがあり、2番目のファイル(条件ファイル)で満たされる複数の条件に基づいて1つのファイル(データファイル)の行にラベルを付ける。awkなどを使用して2番目のファイルの複数の基準に基づいて行を選択する

データファイル:

 
Scaffold Nucleotide_position x SNP1 SNP2 
001 345 . G T 
001 568 . G C 
001 1945 . T C 
001 5001 . T A 
001 5600 . T G 
001 6001 . A T 
001 10889 . G A 
001 12001 . T A 
001 15001 . G A 
002 45 . C T 
002 104 . G T 
002 598 . C A 
002 4800 . T A 
002 5001 . G C 
002 7200 . T A 
002 9845 . A G 
002 11001 . T C 
002 13450 . G A 
003 123 . C T 
003 125 . A G 
003 155 . A C 
003 500 . T C 
003 983 . C G 
003 1001 . G T 
004 2 . A G 
004 567 . T C 
004 901 . C A 
004 5672 . T G 
004 9001 . C G 
004 10098 . A T

条件ファイル:

Scaffold Locus_type Min Max 
001 exon 4456 5543 
001 exon 5678 6668 
001 exon 8955 9939 
001 exon 10778 13444 
002 exon 4785 4800 
002 exon 5200 8000 
002 exon 10000 12000 
003 exon 124 154 
003 exon 854 1025 
004 exon 21 852 
004 exon 8951 9512

所望の出力:

 
001 345 . G T 
001 568 . G C 
001 1945 . T C 
001 5001 . T A *SNP IN EXON 
001 5600 . T G 
001 6001 . A T *SNP IN EXON 
001 10889 . G A *SNP IN EXON 
001 12001 . T A *SNP IN EXON 
001 15001 . G A 
002 45 . C T 
002 104 . G T 
002 598 . C A 
002 4800 . T A *SNP IN EXON 
002 5001 . G C 
002 7200 . T A *SNP IN EXON 
002 9845 . A G 
002 11001 . T C *SNP IN EXON 
002 13450 . G A 
003 123 . C T 
003 125 . A G *SNP IN EXON 
003 155 . A C 
003 500 . T C 
003 983 . C G *SNP IN EXON 
003 1001 . G T *SNP IN EXON 
004 2 . A G 
004 567 . T C 
004 901 . C A 
004 5672 . T G 
004 9001 . C G *SNP IN EXON 
004 10098 . A T

失敗したコマンドを使用してのawk:

 
awk 'NR==FNR{a[$1]=$3 FS=="\t" $4;next}{if (a[$1]==$1 && $3<=$2 && $4>=$2) print $0, "*SNP IN EXON"; else print $0, "";}' Condition_file.txt Data_file.txt

基本的に、2番目のファイル(または条件ファイル)に記載されている特定されたエキソンの範囲(最小値と最大値)に含まれるヌクレオチド(SNP)を含むデータファイルの行のみにラベルを付ける必要があります。私はscaffoldごとに複数のSNPとエクソンを持っています。これはawkコマンドで問題を引き起こしていると思います。

注:私の本当のデータファイルが足場、SNPは、エクソン

これは非常に基本的な問題のように思えるの数千を持っていますが、私は途方に暮れて、私の限られた経験を与えています。ヘルプは非常に高く評価されます。

答えて

1
awk ' 
NR==FNR{     # In condition.txt 
    min[$1]=min[$1]"-"$3;  # Assign the min and max for $1 to array min and max 
    max[$1]=max[$1]"-"$4;  # The delimeter for each value in both array is "-" 
    next 
} 
{ 
    split(min[$1],min1,"-"); # split the value in min & max to min1 & max1 
    split(max[$1],max1,"-"); 
    str=$0; 
    for(i in min1){ 
    if($2>=min1[i]&&$2<=max1[i]) # if the value of $2 in Data.txt meet the criteria 
     str=$0"\t*SNP IN EXON"}; # append "\t*SNP IN EXON" to the string 
    print str 
} 
' Condition.txt Data.txt 
+0

ありがとうCWLiu!あなたの答えは完璧でした。 – jebberson

+0

問題が見つかりました...大規模なデータファイルでCWLiuが提供するawkコマンドを使用するとスクリプトが失敗します。私は大きな配列をメモリにアップロードすることと関係していると思います。たとえば、目的のアプリケーションは、144,000行の「condition.txt」ファイル用です。私が "condition.txt"ファイルを足場グループ(足場1 = 4000行)に縮小すると、CWliuのawkコマンドは正常に動作します。残念ながら、私は〜10000足場を持っており、それに応じてスクリプトを動作させるためにファイルを解析するための別のアプローチを見つける必要があります。 – jebberson

+0

はい、 'awk'には制限があります。大きなファイルをスキャンして処理する別の方法があるはずです。 – CWLiu

関連する問題