Pythonでタンパク質相互作用ネットワークを分析する

金曜日頃からやや風邪気味だったので週末は自宅でひっそり過ごし、今日研究所バイトのために外出したら冬の到来を体感しました。寒い…。

冬生まれの自負と、汗っかきゆえの蒸し暑さ耐性の低さのために、いつも夏と冬だったら冬のほうが過ごしやすいと答えることにしているけど、こういう時はちょっと夏もいいかなあと思ったりする*1

研究所で鼻すすりながらPythonのお勉強をしつつコードを書いて、とりあえず欲しいデータを入手することに成功したので達成感に浸る。 備忘録を兼ねて、スパゲティージェノヴェーゼコードを投下します。

プロジェクトの概要

ヒトのタンパク質相互作用ネットワーク(PIN)のデータを、アルゴリズムで小さなサブネットワークに分割していって、そのサブネットワーク内で薬剤ターゲットに使えそうなタンパク質をスクリーニングするというプロジェクト。

サブネットワーク生成までは研究員のかたが済ませているので、僕が関わるのはスクリーニングのところ。 スクリーニングは手始めにサブネットワークの内部のPPiリンク数=intralinkと、サブネットワーク内部から外部に伸びるリンク数=interlinkを比較してみることにしました。

作業としては大雑把に

  1. サブネットワークのなかのタンパク質の名簿を作る
  2. その名簿をもとに、 intralinkinterlinkをそれぞれ計算する
  3. その情報をひとつのファイルに書き出す

という感じです。

持っているファイルは、

  • 既知の薬剤ターゲット一覧(target.csv
  • サブネットワーク内のタンパクと相互作用するタンパクのペアのファイル(subppi.txt)
  • ヒト全PPiのペアファイル(wholeppi.txt)

の3つ。subppi.txtwholeppi.txt

protein interacting protein
proteinA proteinX
proteinA proteinY
proteinB proteinZ

みたいな感じで1列目にタンパクAがあって、それと相互作用することが知られているタンパクX、Yがタブ区切りで2列目に並んでるフォーマット。 同じタンパク質が何度も登場するので、まずは重複を削って名簿リストを作成します。

1. サブネットワークの名簿作り
import csv
namelist1 = []
namelist2 = []
with open('subppi.txt', 'r') as f:
    reader = csv.reader(f, delimiter='\t')
    for row in reader: 
        reader0 = row[0] 
        namelist1.append(reader0) 
        reader1 = row[1]
        namelist2.append(reader1)

まずはリスト型を用意しておいて、with statementを使ってsubppi.txtを開く。 withでファイルを開けば、close()とかflush()とかが必要なくて便利ですね。

Pythoncsvモジュールをつかってファイルの中身を読み込み、一列目の内容row[0]reader0で一旦受け取ってから、namelist1にappendする。 同様に二列目の内容もnamelist2にappend。

namelist1はサブネットワーク内のタンパク質が重複しながらぜんぶ入っているリストなので、これをつかって名簿を作る。

pnamelist = []
pnamelist.extend(x for x in namelist1 if x not in pnamelist)

名簿用の新しいリストpnamelistを用意して、namelist1の内容をforループで回しつつ、pnamelistにまだ入っていないタンパク質に限って追加する。 名簿完成!

2. 名簿を元にintralinkとinterlinkを計算する

いま作った名簿pnamelistに登場するタンパク質について、サブネットワーク内部の相互リンク数と、サブネットワーク外にあるタンパク質との相互リンク数を計算する。

まずはサブネットワーク内部のリンク数intralinkの計算。

intralink = {}
compnamelist = []
compnamelist = namelist1 + namelist2
for x in pnamelist:
    intralink[x]  = compnamelist.count(x)

ここで最初に出てきたsubppi.txtの両列をリスト化したnamelist1namelist2compnamelistに入れ、subppi.txtの全項目を1つのリストにまとめます。 つぎにこれを使って、pnamelistに符号する項目の個数を.countで数えてdict型のintralinkに{proteinA: 2, proteinB:1,}という感じで突っ込んでいく。

つぎにinterlinkの計算、、、といきたいところだけど、都合よくサブネットワーク内部から外に伸びるリンクだけを集めたファイルが有るわけではない。 そこで、pnamelistに登場するタンパク質の全リンクからinterlinkだけを引いて、intralinkを計算することに。 というわけで、全PPiデータのwholeppi.txtについて、だいたい上記と同じことをして全部入りリストwholelistを作成して、そこにpnamelistを回してinterlinkを計算する。 さらに、intralinkからinterlinkを引いたrankを計算することで、サブネットワーク内部でのリンク数のほうが多いタンパク質をランク付けできるようにする。

namelist3 = []
namelist4 = []
wholelist = []
wholelink = {}
interlink = {}
rank = {}

with open('wholeppi.txt', 'r') as f:
    reader = csv.reader(f, delimiter='\t')
    for row in reader: 
        reader0 = row[0] 
        namelist3.append(reader0) 
        reader1 = row[1]
        namelist4.append(reader1)

wholelist = namelist3 + namelist4

for x in pnamelist:
   wholelink[x] = wholelist.count(x)

for x in wholelink:
    interlink[x] = wholelink[x] - intralink[x]
    rank[x] = intralink[x] - interlink[x]

これで、サブネットワーク内の各タンパク質について、その総リンク数wholelink、内部リンク数intralink、外部リンク数interlink、ランクrankがわかった。

最後に、既知の薬剤ターゲットかどうかを判別しておきたい。

import csv
target = []
truefalse = {}
with open('target.csv', 'r') as f:
    reader = csv.reader(f, delimiter='\n')
    for row in reader:
        r = row[0]
        elements = r.strip()
       target.append(elements)

for x in pnamelist:
    if x in target:
        truefalse[x] = 1
    if x not in kitarget:
        truefalse[x] = 0  

まず薬剤ターゲットリストtarget.csvを開き、項目をlist型targetに納める。 つぎにpnamelistに登場する各タンパク質について、もしtargetにも登場するならdict型truefalseの値を1に、登場しない場合は0にする。

ファイル書き出し

これですべての情報が揃ったので、あとはこれをまとめてひとつのtxtファイルに書き出すだけ。

import csv
import sys
with open('result.txt', 'w') as f:
    writer = csv.writer(f, delimiter = '\t')
    writer.writerow( ('Protein', 'Total Links', 'Interlinks', 'Intralinks', 'rank', 'known target?') )
    for x in pnamelist:
        writer.writerow((x, wholelink[x], interlink[x], intralink[x], rank[x], truefalse[x]))

まずはヘッダー行に各列の名前を書き込んで、そのあとpnamelistを回してタンパク名、総リンク数、外部リンク数、内部リンク数、ランク、既知ターゲット判別の計6項目をcsvモジュールの.writerowメソッドで書き込む。 初めは.writerow(x,...)としていたところTypeError: writerow() takes exactly one argument (6 given)と怒られてしまったので、かなり調べまわった後に.writerow( (x,...) )とカッコを二重にすれば良いということに気づいた。

結果

以上の作業の結果、このようなファイルを出力することができた。

Protein Total Links Interlinks Intralinks Rank Known Target?
ProteinA 200 150 50 -100 0
ProteinB 30 10 20 10 1

やったね!

所感

  • 先週はpnamelistを作るだけで一日かかったけど、今日はファイル出力までをこなせてとてもよかった。Stack Overflow - Where Developers Learn, Share, & Build Careersの神々に感謝。
  • 来週以降はこのデータをこね回してなにかを発見したいところ。
  • この記事を書くだけでコード書くのと同じくらいエネルギー使った気がする。
  • ふう。
  • ここまで読んでくださってありがとう。

*1:そもそもその質問は夏場に発される場合が多い気がする

Related Posts Plugin for WordPress, Blogger...