Pythonでタンパク質相互作用ネットワークを分析する
金曜日頃からやや風邪気味だったので週末は自宅でひっそり過ごし、今日研究所バイトのために外出したら冬の到来を体感しました。寒い…。
冬生まれの自負と、汗っかきゆえの蒸し暑さ耐性の低さのために、いつも夏と冬だったら冬のほうが過ごしやすいと答えることにしているけど、こういう時はちょっと夏もいいかなあと思ったりする*1。
研究所で鼻すすりながらPythonのお勉強をしつつコードを書いて、とりあえず欲しいデータを入手することに成功したので達成感に浸る。 備忘録を兼ねて、スパゲティージェノヴェーゼコードを投下します。
プロジェクトの概要
ヒトのタンパク質相互作用ネットワーク(PIN)のデータを、アルゴリズムで小さなサブネットワークに分割していって、そのサブネットワーク内で薬剤ターゲットに使えそうなタンパク質をスクリーニングするというプロジェクト。
サブネットワーク生成までは研究員のかたが済ませているので、僕が関わるのはスクリーニングのところ。
スクリーニングは手始めにサブネットワークの内部のPPiリンク数=intralink
と、サブネットワーク内部から外部に伸びるリンク数=interlink
を比較してみることにしました。
作業としては大雑把に
- サブネットワークのなかのタンパク質の名簿を作る
- その名簿をもとに、
intralink
とinterlink
をそれぞれ計算する - その情報をひとつのファイルに書き出す
という感じです。
持っているファイルは、
- 既知の薬剤ターゲット一覧(
target.csv
) - サブネットワーク内のタンパクと相互作用するタンパクのペアのファイル(
subppi.txt
) - ヒト全PPiのペアファイル(
wholeppi.txt
)
の3つ。subppi.txt
とwholeppi.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()とかが必要なくて便利ですね。
Pythonのcsv
モジュールをつかってファイルの中身を読み込み、一列目の内容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
の両列をリスト化したnamelist1
とnamelist2
をcompnamelist
に入れ、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:そもそもその質問は夏場に発される場合が多い気がする