3番目のリストファイルに基づいて2つのファイルの行をフィルタリングします。

3番目のリストファイルに基づいて2つのファイルの行をフィルタリングします。

list_filefile1および3つのファイルがあります。ペアに基づいて行全体を抽出し、結果を出力にリンクしたいとfile2思います。file1file2list_file

つまり、file1からfile2名前のある行を抽出するだけです。4列最初の列と2番目の列の名前をそれぞれ一致させ、list_fileリストファイルに表示されているのと同じペアの順序で出力の行全体を連結します。

名前を入力する列1list_fileとに存在するfile1名前2列list_fileに存在しますfile2

リストファイル:

uth1.g20066 uth2.g18511
uth1.g3149  uth2.g22348
uth1.g20067 uth2.g18512
uth1.g20068 uth2.g18514
uth1.g3154  uth2.g22355

ファイル1

ut1A    11256   13613   uth1.g20065
ut1A    25598   47989   uth1.g20066
ut1A    39912   40142   uth1.g3148
ut1A    40324   40617   uth1.g3149
ut1A    40699   41034   uth1.g3150

ファイル2

ut1B    16951   39342   uth2.g18511
ut1B    31265   31495   uth2.g22347
ut1B    31677   31970   uth2.g22348
ut1B    32052   32387   uth2.g22349
ut1B    41596   46862   uth2.g18522

希望の出力:

ut1A    25598   47989   uth1.g20066 ut1B    16951   39342   uth2.g18511
ut1A    40324   40617   uth1.g3149  ut1B    31677   31970   uth2.g22348

これを行うには、以下のPythonコードを試しましたが、うまくいきますが、大きな入力ファイルでは非常に遅く(ループが多い)、より簡潔にすることをお勧めします。あるいは、まったく新しいスクリプトを使用するのも興味深いでしょう(おそらくawkを使う)。ありがとうございます。

data = open("list_file.txt")

data1 = open("file1.txt")
all_lines1 = data1.readlines() 

data2 = open("file2.txt")
all_lines2 = data2.readlines()

output = open("output.txt", "w")

for line in data:

    columns = line.split( )
    geneH1data = columns[0]
    geneH2data = columns[1]

    for line1 in all_lines1:

        columns1 = line1.split( )
        chr1 = columns1[0]
        start1 = int(columns1[1])
        end1 = int(columns1[2])
        geneH1data1 = columns1[3]

        for line2 in all_lines2:

            columns2 = line2.split( )
            chr2 = columns2[0]
            start2 = int(columns2[1])
            end2 = int(columns2[2])
            geneH2data2 = columns2[3]

            if geneH1data==geneH1data1 and geneH2data==geneH2data2:
                output.write(chr1 + " " + str(start1) + " " + str(end1) + " " + geneH1data + " " + chr2 + " " + str(start2) + " " + str(end2) + " " + geneH2data + '\n')

出力.txt

ut1A 25598 47989 uth1.g20066 ut1B 16951 39342 uth2.g18511
ut1A 40324 40617 uth1.g3149 ut1B 31677 31970 uth2.g22348

ベストアンサー1

GNU awkを使用して、次の操作を行いますARGIND

$ awk '
    ARGIND<3 { a[ARGIND,$4]=$0; next }
    ((1,$1) in a) && ((2,$2) in a) { print a[1,$1], a[2,$2] }
' file1 file2 list_file
ut1A    25598   47989   uth1.g20066 ut1B    16951   39342   uth2.g18511
ut1A    40324   40617   uth1.g3149 ut1B    31677   31970   uth2.g22348

GNU awkがない場合は、次のように調整してください。

$ awk '
    FNR==1 { argind++ }
    argind<3 { a[argind,$4]=$0; next }
    ((1,$1) in a) && ((2,$2) in a) { print a[1,$1], a[2,$2] }
' file1 file2 list_file
ut1A    25598   47989   uth1.g20066 ut1B    16951   39342   uth2.g18511
ut1A    40324   40617   uth1.g3149 ut1B    31677   31970   uth2.g22348

これはどのawkでも動作します。出力をスペース区切りではなくタブ区切りとして指定するには、再調整するだけです。

$ awk '
    BEGIN { OFS="\t" }
    FNR==1 { argind++ }
    argind<3 { a[argind,$4]=$0; next }
    ((1,$1) in a) && ((2,$2) in a) { print a[1,$1], a[2,$2] }
' file1 file2 list_file
ut1A    25598   47989   uth1.g20066     ut1B    16951   39342   uth2.g18511
ut1A    40324   40617   uth1.g3149      ut1B    31677   31970   uth2.g22348

おすすめ記事